第四章:双向循环链表

  双向循环链表,说穿了其实是单链表的一个变种。结点结构比单链表多了一个指向头一个结点的前驱结点,由于要实现循环。所以链表的尾结点需要与头结点形成一个环状,就跟蛇用头咬住自己尾巴是类似的。双向循环链表在现实生活中的应用是极其多的,这里实现了一个简单的模板,如有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;
}

 

 

今天偷懒了,不想测试了。想测试的自己测下,没空测了,因为代码比较容易的。看下去,一目了然。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值