一、实现
CList作为一个链表类,它的成员是由CNode组成。
CNode有两个属性,tElement用于指向当前的节点,next用于指向下一个节点
定义List.h文件
#pragma once
#ifndef _List_
#define _List_
#include <Windows.h>
//链表节点
template<typename T>
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 <typename T>
class CList
{
public:
CList() : dwCount(0), head(0) { }
CList(T* tElement) : dwCount(1), head(new CNode<T>(tElement)) { }
virtual ~CList() { }
public:
void Append(CNode<T>*& node, T* tElement);//添加
void Insert(T* tElement);//插入
bool Remove(T* tElement);//删除
DWORD Count() const { return dwCount; }//节点数量
CNode<T>*& 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<T>* head;
DWORD dwCount;
};
#endif // _List_
定义CList.cpp
#include "CList.h"
template<typename T>
void CList<T>::Append(CNode<T>*& node, T* tElement)
{
if (node == NULL)
{
dwCount++;
node = new CNode<T>(tElement);
return;
}
Append(node->Next(), tElement);
}
template<typename T>
void CList<T>::Insert(T * tElement)
{
dwCount++;
if (head == NULL)
{
head = new CNode<T>(tElement);
return;
}
CNode<T>* tmp = head;
head = new CNode<T>(tElement);
head->Next() = tmp;
}
template<typename T>
bool CList<T>::Remove(T * tElement)
{
if (head == NULL)
{
return NULL;
}
if (head->Element() == tElement)
{
CNode<T>* tmp = head;
head = head->Next();
delete tmp;
dwCount--;
return true;
}
CNode<T>* tmp = head;
CNode<T>* 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<typename T>
T * CList<T>::GetLast()
{
if (head)
{
CNode<T>* tmp = head;
while (tmp->Next())
{
tmp = tmp->Next();
}
return tmp->Element();
}
return NULL;
}
template<typename T>
T * CList<T>::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<T>* lst = head->Next();
while (lst != NULL)
{
if (lst->Element() == tElement)
{
return lst->Next() != NULL ? lst->Next()->Element() : NULL;
}
lst = lst->Next();
}
return NULL;
}
template<typename T>
T * CList<T>::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 <typename T>
CList<T>::CList(const CList& list)
{
head = new CList<T>;
memcpy(head, list.head, CList<T>);
dwCount = list.dwCount;
}
template <typename T>
CList<T>& CList<T>::operator= (const CList& list)
{
dwCount = list.dwCount;
CList<T>* temp = new CList<T>;
memcpy(temp, list.head, CList<T>);
delete[]head;
head = temp;
return *this;
}
二、注释
首先,解释一下CList
类。为了更方便地处理,该链表由CNode
类型的元素组成。CNode
类有两个特征:tElement
指针(指向用户自定义的元素)和next
指针(指向链表下一个项);实现了两个方法:Element
和Next
。Element
方法返回当前元素地址的指针,Next
方法返回下一个项地址的引用。
Find
方法显然是一个高级特性,针对未定义类型T和未定义的Function
方法(带tParameter
参数)设计。假设要使用一个包含学生对象的链表,例如迭代数据(如,使用GetNext
方法)或查找某个学生。如果有可能为将来定义的类型实现一个返回unsigned long
类型(DWORD
)的方法,而且该方法要把未知类型数据与dwValue
参数做比较,应该怎么做?例如,假设要根据学生的ID找出这名学生,可以使用下面的代码:
#include <windows.h>
#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<CStudent>* list = new CList<CStudent>();
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