给个新建模板类的例子MyNodeList <pixeldata> nd=new MyNodeList<pixeldata>();//链表初始化 其中pixeldata是自己定义的一个结构体
//Node.h
template <class T>
class Node
{
private:
Node<T>* next;
T data;
public:
Node();
Node(const T& item,Node<T>* ptrnext=NULL);
~Node();
void SetData(T &item); //设置节点的数据域
T GetData() const; //取节点的数据域
void InsertAfter(Node<T> *p); //在节点后插入一个节点P
Node<T>* DeleteAfter(); //删除节点邻接的下一个节点
Node<T>* NextNode() const; //取节点邻接的下一个节点
};//---------------
template<class T>
Node<T>::Node():next(NULL){} //空的构造函数
template<class T>
Node<T>::Node(const T &item,Node<T>* ptrnext)
{
data=item;
next=ptrnext;
}//-----------------------------------------------
template<class T>
Node<T>::~Node() //析构函数
{
delete[] next;
}//-----------------------------------------------
template<class T>
void Node<T>:: SetData(T &item) //设置节点的数据域
{
data=item;
}//-----------------------------------------------
template<class T>
T Node<T>::GetData()const //取节点的数据域
{
return data;
}//-----------------------------------------------
template<class T>
void Node<T>::InsertAfter(Node<T>*p) //在节点后插入一个节点P
{
p->next=next;
next=p;
}//-----------------------------------------------
template<class T>
Node<T>* Node<T>::DeleteAfter() //删除节点邻接的下一个节点
{
if(next==NULL)
return NULL;
Node<T>* tempptr=next;
next=tempptr->next;
return tempptr;
}//-----------------------------------------------
template<class T>
Node<T>* Node<T>::NextNode()const //取节点邻接的下一个节点
{
return next;
}//-------------------------------------------------------------------
//NodeList.h
#include "stdafx.h"
template <class T>
class NodeList
{
private:
Node<T> *front,*rear; //表头和表尾指针
Node<T> *currptr; //指向当前节点的指针
Node<T> *GetNode(const T &item,Node<T>*ptrNext=NULL); //构造一个节点
public:
NodeList();
NodeList(const NodeList<T>& L); //拷贝构造函数
~NodeList();
void Reset(); //复位,将currptr重新指向表头
void InsertFront(const T& item); //表头插入节点
void InsertRear(const T& item); //表尾插入节点
void InsertAfter(const T& item); //在当前节点(currptr所指节点)处插入节点
int Find(const T &item); //在链表中查找item,若在链表中返回1并把currptr指向item第一次出现的 节点;若没有返回0
void LSort(); //按数据域大小从小到大排序
void Reverse(); //倒置链表
int IsEmpty(); //链表是否为空
int IsEndOfNodeList(); //当前指针currptr是否到达表尾
void Next(); //当前指针currptr指向下一个节点,并返回该节点
T Data(); //取当前节点的数据域
Node<T>* DeleteAt(); //删除当前节点
void PrintNodeList(); //打印链表
};//-----------------------------------------------
template<class T>
NodeList<T>::NodeList():front(NULL),rear(NULL),currptr(NULL){}
//-----------------------------------------------
template<class T>
NodeList<T>::NodeList(const NodeList<T>& L) //拷贝构造函数
{
L.Reset();
while(!L.IsEndOfNodeList())
{
InsertRear(L.Data());
L.Next();
}
InsertRear(L.Data());
}//-----------------------------------------------
template<class T>
NodeList<T>::~NodeList()
{
delete[] front;
}//-----------------------------------------------
template<class T>
Node<T>* NodeList<T>::GetNode(const T &item,Node<T>*ptrNext) //构造一个节点
{
Node<T>* newNode;
newNode=new Node<T>(item,ptrNext);
if(newNode==NULL)
{
cerr<<"Memory allocation failure!";
exit(1);
}
return newNode;
}//-----------------------------------------------
template<class T>
void NodeList<T>::Reset() //复位,将currptr重新指向表头
{
currptr=front;
}//-----------------------------------------------
template<class T>
void NodeList<T>::InsertFront(const T& item) //表头插入节点
{
if(front==NULL) //如果表为空,插入一个节点后,表头和表尾指针都要指向插入节点
{
front=rear=GetNode(item,front);
}
else
{
front=GetNode(item,front);
}
}//-----------------------------------------------
template<class T>
void NodeList<T>::InsertRear(const T& item) //表尾插入
{
if(front==NULL) //如果表为空,插入一个节点后,表头和表尾指针都要指向插入节点
{
front=rear=GetNode(item,front);
}
else
{
rear->InsertAfter(GetNode(item)); //表不为空时,在表尾插入节点,并将rear重新指向新的表尾
rear=rear->NextNode();
}
}//-----------------------------------------------
template<class T>
void NodeList<T>::InsertAfter(const T& item) //在当前节点后插入节点
{
if(currptr!=NULL) //若表不为空,则currptr有值,可以插入
{
if(rear==currptr)
{
InsertRear(item);
}
else
{
currptr->InsertAfter(GetNode(item));
}
}
else //若表为空,则currptr指向空,插入失败
{
cerr<<"currptr is null!!";
}
}//-----------------------------------------------
template<class T>
int NodeList<T>::Find(const T& item) //在链表中查找item,若在链表中返回1并把currptr指向item第一次出现的节点;若没有返回0
{
Reset();
while(currptr!=NULL&&Data()!=item)
{
currptr=currptr->NextNode();
}
if(currptr==NULL)
return 0;
return 1;
}//-----------------------------------------------
template<class T>
void NodeList<T>::LSort() //按数据域大小从小到大排序,链表若不会空,每次取链表中最大的节点放入临时链表中,并从原来链表中删除
{
if(front==NULL) //直到原来链表为空,排序完成
{
cerr<<"NodeList is empty!";
}
else
{
Node<T> *lptr=new Node<T>();
Node<T> *rptr; //记住排好序后的表尾,即链表中最大的节点
Node<T> *tempptr;
int flag=0; //标记排好序后的表尾
while(!IsEmpty())
{
tempptr=front;
Reset();
while(currptr!=NULL) //每次循环都依次取链表中一个节点与tempptr比较,并将大的放入tempptr
{
if(tempptr->GetData()<Data())
tempptr=currptr;
currptr=currptr->NextNode();
}
if(flag==0)
rptr=tempptr; //记住排好序后的表尾
flag=1;
currptr=tempptr; //让currptr指向链表中最大的节点,及当前节点就是最大节点
lptr->InsertAfter(DeleteAt()); //将最大的节点从原来链表中删除,并放入临时链表中
}
front=lptr->NextNode(); //将排好序的链表复制给要求排序的链表
rear=rptr; //将排好序的表尾赋值给rear
}
}//-----------------------------------------------
template<class T>
void NodeList<T>::Reverse() //倒置链表,从表头删除并插入表尾
{
if(front==NULL)
{
cerr<<"NodeList is empty!";
}
else
{
Node<T>* fptr;
fptr=front; //记住开始的表头节点,以便赋值给倒置后的表尾
while(front!=rear)
{
Reset();
rear->InsertAfter(DeleteAt()); //表头删除插入表尾
}
rear=fptr; //原来的表头节点赋值给倒置后的表尾
}
}//-----------------------------------------------
template<class T>
int NodeList<T>::IsEmpty()
{
return front==NULL;
}
template<class T>
T NodeList<T>::Data() //取当前节点的数据域
{
return(currptr->GetData());
}//-----------------------------------------------
template<class T>
int NodeList<T>::IsEndOfNodeList()
{
return currptr==rear;
}//-----------------------------------------------
template<class T>
void NodeList<T>::Next()
{
currptr=currptr->NextNode();
}//-----------------------------------------------
template<class T>
Node<T>* NodeList<T>::DeleteAt() //删除当前节点
{
if(currptr==front)
{
if(front==rear) //若链表中只有一个节点,表头表尾指针都要指向空
front=rear=NULL;
else
front=currptr->NextNode(); //若当前节点就是表头,删除后,表头指针顺序后延
}
else
{
Node<T>* tempptr=front;
while(tempptr->NextNode()!=currptr) //若当前节点不是表头,找到当前节点的前一个节点,通过Node<T>中定义的DeleteAfter()
{ //删除当前节点
tempptr=tempptr->NextNode();
}
tempptr->DeleteAfter();
}
return currptr;
}//-----------------------------------------------
template<class T>
void NodeList<T>::PrintNodeList() //打印链表,每打印十个,换行
{
Node<T> *tempptr=front;
int count=1;
while(tempptr!=NULL)
{
cout<<tempptr->GetData()<<" ";
if((count++)%10==0)
cout<<endl;
tempptr=tempptr->NextNode();
}
cout<<endl;
}//-----------------------------------------------
本文介绍了一个使用模板类实现的链表数据结构,包括节点类和链表类的设计与实现,涵盖了链表的基本操作如插入、删除、排序等。
595

被折叠的 条评论
为什么被折叠?



