双向循环链表,说穿了其实是单链表的一个变种。结点结构比单链表多了一个指向头一个结点的前驱结点,由于要实现循环。所以链表的尾结点需要与头结点形成一个环状,就跟蛇用头咬住自己尾巴是类似的。双向循环链表在现实生活中的应用是极其多的,这里实现了一个简单的模板,如有bug,请及时告诉我。
下面给出代码实现:
///
// Book name : C++ structure and algorithm
// FileName : DNode.cpp
// Version : 1.0
// Author : Yangfei
// Date : 2010-4-10 20:53:50
// Comment : 双向循环链表类
//
///
///
// 结点结构:| *prior | data | *next|
///
template <class T>
class DNode
{
public:
T data;
DNode<T>* prior;
DNode<T>* next;
DNode():data(T()),prior(NULL),next(NULL){}
DNode(T _data):data(_data),prior(NULL),next(NULL){}
};
//不带头结点的双向循环链表定义
template <class T>
class DList
{
private:
DNode<T>* first;
int count;
public:
//双向循环链表的基本操作定义,13项
DList():first(NULL),end(NULL),count(0){}
void InitDlist(T&);
bool IsEmpty();
void InsertatposBefore(int pos,T& data);
void InsertatposAfter(int pos,T& data);
void TraverseDlistfirst();
void TraverseDlistback();
void Getatpos(int pos,T& data);
void GetPrioratpos(int pos,T& data);
void GetNextatpos(int pos, T& data);
void DeleteAtpos(int pos);
void ClearDlist();
int GetCount();
};
//template function定义
template <class T>
void DList<T>::InitDlist(T& a)
{
first=new DNode<T>();
if(first==NULL)
{
cout<<"Out of Memory!"<<endl;
}
else
{
first->data=a;
first->next=first;
first->prior=first;
}
}
template <class T>
bool DList<T>::IsEmpty()
{
//判断双向循环链表是否为空有两种方法:1.通过count2.通过first指针
if(count==0)
return true;
else
return false;
}
template <class T>
void DList<T>::InsertatposBefore(int pos,T& data)
{
assert(pos>0&&pos<=count);
DNode<T>* tempNode=first;
DNode<T>* newNode=new DNode<T>();
if(newNode==NULL)
cout<<"Out of Memorry!"<<end;
newNode->data=data;
for(int i=1;i<=pos-1;i++)
tempNode=tempNode->next;
//在某位置前插入新结点
newNode->next=tempNode;
newNode->prior=tempNode->prior;
tempNode->prior->next=newNode;
tempNode->prior=newNode;
count++;
}
template <class T>
void DList<T>::InsertatposAfter(int pos,T& data)
{
assert(pos>0&&pos<=count);
DNode<T>* tempNode=first;
DNode<T>* newNode=new DNode<T>();
if(newNode==NULL)
cout<<"Out of Memorry!"<<end;
newNode->data=data;
for(int i=1;i<=pos-1;i++)
tempNode=tempNode->next;
//在某位置后插入新结点
newNode->prior=tempNode;
newNode->next=tempNode->next;
tempNode->next->prior=newNode;
tempNode->next=newNode;
count++;
}
template <class T>
void DList<T>::TraverseDlistfirst()
{
assert(count>0);
DNode<T>* tempNode=first;
while(tempNode)
{
cout<<tempNode->data<<" ";
tempNode=tempNode->next;
if(tempNode==first)
break;
}
}
template <class T>
void DList<T>::TraverseDlistback()
{
assert(count>0);
DNode<T>* tempNode=first->prior;
while(tempNode)
{
cout<<tempNode->data<<" ";
tempNode=tempNode->prior;
if(tempNode==first)
break;
}
}
template <class T>
void DList<T>::Getatpos(int pos,T& data)
{
assert(pos>0&&pos<=count);
DNode<T>* tempNode=first;
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
data=tempNode->data;
}
template <class T>
void DList<T>::GetPrioratpos(int pos,T& data)
{
assert(pos>0&&pos<=count);
DNode<T>* tempNode=first;
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
data=tempNode->prior->data;
}
template <class T>
void DList<T>::GetNextatpos(int pos,T& data)
{
assert(pos>0&&pos<=count);
DNode<T>* tempNode=first;
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
data=tempNode->next->data;
}
template <class T>
void DList<T>::DeleteAtpos(int pos)
{
assert(pos>0&&pos<=count);
DNode<T>* tempNode=first;
for(int i=1;i<pos;i++)
tempNode=tempNode->next;
//删除元素,指针指示
tempNode->prior->next=tempNode->next;
tempNode->next->prior=tempNode->prior;
delete tempNode;
}
//清空链表
template <class T>
void DList<T>::ClearDlist()
{
if(!IsEmpty())
{
DNode<T>* temp1Node=first;
Dnode<T>* tempNode;
while(temp1Node!=NULL)
{
tempNode=temp1Node;
temp1Node=temp1Node->next;
delete tempNode;
if(temp1Node==first)
{
first=NULL;
break;
}
}
}
}
//返回双向循环链表的长度(元素个数)
template <class T>
int DList<T>::GetCount()
{
return count;
}
int main()
{
//DList测试
DList<int> dlist;
return 0;
}
今天偷懒了,不想测试了。想测试的自己测下,没空测了,因为代码比较容易的。看下去,一目了然。