线性链表的实现

一、实现

CList作为一个链表类,它的成员是由CNode组成。

CNode有两个属性,tElement用于指向当前的节点,next用于指向下一个节点

定义List.h文件

#pragma once
#ifndef _List_
#define  _List_

#include 

//链表节点
template
class CNode
{
public:
	CNode(T* tElement) :tElement(tElement), next(0) {}
	T* Element() const { return tElement; }
	CNode*& Next() { return next; }

private:
	T* tElement;//用于指示当前节点
	CNode* next;//用于指示下一个节点
};


template 
class CList
{
public:
	CList() : dwCount(0), head(0) { }
	CList(T* tElement) : dwCount(1), head(new CNode(tElement)) { }
	virtual ~CList() { }
public:
	void Append(CNode*& node, T* tElement);//添加
	void Insert(T* tElement);//插入
	bool Remove(T* tElement);//删除
	DWORD Count() const { return dwCount; }//节点数量
	CNode*& Head() { return head; }//节点头
	T* GetFirst() { return head != NULL ? head->Element() : NULL; }
	T* GetLast();
	T* GetNext(T* tElement);
	T* Find(DWORD(*Function)(T* tParameter), DWORD dwValue);

protected:
	CList(const CList& list);//防止默认拷贝发生
	CList& operator = (const CList& list);
private:
	CNode* head;
	DWORD dwCount;
};

#endif // _List_

定义CList.cpp

#include "CList.h"

template
void CList::Append(CNode*& node, T* tElement)
{
	if (node == NULL)
	{
		dwCount++;
		node = new CNode(tElement);
		return;
	}

	Append(node->Next(), tElement);
}

template
void CList::Insert(T * tElement)
{
	dwCount++;
	if (head == NULL)
	{
		head = new CNode(tElement);
		return;
	}

	CNode* tmp = head;
	head = new CNode(tElement);
	head->Next() = tmp;
}

template
bool CList::Remove(T * tElement)
{
	if (head == NULL)
	{
		return NULL;
	}

	if (head->Element() == tElement)
	{
		CNode* tmp = head;
		head = head->Next();

		delete tmp;
		dwCount--;

		return true;
	}

	CNode* tmp = head;
	CNode* lst = head->Next();

	while (lst != NULL)
	{
		if (lst->Element() == tElement)
		{
			tmp->Next() = lst->Next();

			delete lst;
			dwCount--;

			return true;
		}

		lst = lst->Next();
		tmp = tmp->Next();
	}

	return false;
}

template
T * CList::GetLast()
{
	if (head)
	{
		CNode* tmp = head;
		while (tmp->Next())
		{
			tmp = tmp->Next();
		}
		return tmp->Element();
	}

	return NULL;
}

template
T * CList::GetNext(T * tElement)
{
	if (head == NULL)
	{
		return NULL;
	}

	if (tElement == NULL)
	{
		return GetFirst();
	}

	if (head->Element() == tElement)
	{
		return head->Next() != NULL ? head->Next()->Element() : NULL;
	}

	CNode* lst = head->Next();

	while (lst != NULL)
	{
		if (lst->Element() == tElement)
		{
			return lst->Next() != NULL ? lst->Next()->Element() : NULL;
		}

		lst = lst->Next();
	}

	return NULL;
}

template
T * CList::Find(DWORD(*Function)(T *tParameter), DWORD dwValue)
{
	try
	{
		T* tElement = NULL;
		while (tElement = GetNext(tElement))
		{
			if (Function(tElement) == dwValue)
			{
				return tElement;
			}
		}
	}
	catch (...) {}

	return NULL;
}

template 
CList::CList(const CList& list)
{
	head = new CList;
	memcpy(head, list.head, CList);
	dwCount = list.dwCount;
}

template 
CList& CList::operator= (const CList& list)
{
	dwCount = list.dwCount;
	CList* temp = new CList;
	memcpy(temp, list.head, CList);

	delete[]head;
	head = temp;
	return *this;
}






二、注释

首先,解释一下CList类。为了更方便地处理,该链表由CNode类型的元素组成。CNode类有两个特征:tElement指针(指向用户自定义的元素)和next指针(指向链表下一个项);实现了两个方法:ElementNextElement方法返回当前元素地址的指针,Next方法返回下一个项地址的引用。

Find方法显然是一个高级特性,针对未定义类型T和未定义的Function方法(带tParameter参数)设计。假设要使用一个包含学生对象的链表,例如迭代数据(如,使用GetNext方法)或查找某个学生。如果有可能为将来定义的类型实现一个返回unsigned long类型(DWORD)的方法,而且该方法要把未知类型数据与dwValue参数做比较,应该怎么做?例如,假设要根据学生的ID找出这名学生,可以使用下面的代码:

#include 
#include "CList.h"

class CStudent
{
public:
  CStudent(DWORD dwStudentId) : dwStudentId(dwStudentId){ }
  static DWORD GetStudentId(CStudent* student)
  {
    DWORD dwValue = student->GetId();
    return dwValue;
  }
  DWORD GetId() const
  {
    return dwStudentId;
  }
private:
  DWORD dwStudentId;
};

int main()
{
  CList* list = new CList();
  list->Insert(new CStudent(1));
  list->Insert(new CStudent(2));
  list->Insert(new CStudent(3));
  CStudent* s = list->Find(&CStudent::GetStudentId, 2);
  if (s != NULL)
  {
    // 找到s
  }
  return 0;
}```

 

参考:

https://yq.aliyun.com/articles/92420/

https://blog.csdn.net/qq_33373173/article/details/86564959

https://blog.csdn.net/lwbeyond/article/details/6202256

https://blog.csdn.net/zhuiqiuzhuoyue583/article/details/80450843

 

 

 

你可能感兴趣的:(LeetCode)