C++双向循环链表

来源:互联网 发布:速达软件功能 编辑:程序博客网 时间:2024/06/06 09:29
                                   实现双向循环,具有chain类的所有功能动态链表的实现十分简单。它的好处在于动态分配内存空间,有效避免了各种问题,同时通过插入链表可以实现插入排序,也就是说,当你把新的数据输入时,数据所在的位置已经是按顺序排好的了,在输出时,只要遍历链表就可以了,用双向循环链表实现的好处在于能够按两种顺序(从大到小,从小到大)对链表进行遍历,实现起来相当方便。//DoubleCircular.h#include<iostream>#include"xcept.h"using namespace std;template<class T>class DoubleCircular;template<class T>class DoubleNode{ friend class DoubleCircular<T>;  private:   T data;   DoubleNode<T> *left  ,*right;};template<class T>class DoubleCircular {   public:      DoubleCircular() {rightEnd = 0;} //构造函数     ~DoubleCircular(); //析构函数      bool IsEmpty() const {return rightEnd == 0;} //如果表为空则返回true,否则返回false      int Length() const; //返回表的大小       bool Find(int k, T& x) const; //寻找表中第k个元素,并把它保存到x中;如果不存在,则返回false      int Search(const T& x) const; //返回元素x在表中的位置;如果x不在表中,则返回0      DoubleCircular<T>& Delete(int k, T& x); //删除表中第k个元素,并把它保存到x中,函数返回修改后的线性表      DoubleCircular<T>& Insert(int k, const T& x); //在第k个元素之后插入x,函数返回修改后的线性表      void Output(ostream& out) const; //把线性表放入输出流out之中   private:      DoubleNode<T>  *rightEnd; //指向最右端节点的指针}; template<class T>DoubleCircular<T>::~DoubleCircular(){   if (!rightEnd) return; // 链表为空   DoubleNode<T> *current =rightEnd->left,                 *next; //声明当前指针指向最右端节点的左以及下一个指针next          while (current !=rightEnd) {      next = current->left;//下一指针指向当前指针的左端      delete current;//释放掉当前指针      current = next;//当前指针指向下一指针      }   delete rightEnd;//释放掉最右端指针}template<class T>int DoubleCircular<T>::Length() const{ int len = 0;//初始化len为0   if (!rightEnd) return 0;  //链表为空   DoubleNode<T> *current =rightEnd->left;//当前指针指向最右端节点的左   while (current != rightEnd) {     current = current->left;//下一指针指向当前指针的左端  len++;//len后加加   }   len++;  // for last node   return len;}template<class T>bool DoubleCircular<T>::Find(int k, T& x) const//寻找表中第k个元素,并把它保存到x中;如果不存在,则返回false{   if (k < 1 || !rightEnd) return false;//k无意义或者链表为空   DoubleNode<T> *current = rightEnd->left;//当前指针指向最右端节点的左   int index = 1;//标记下标为1    while (index < k && current !=rightEnd) {      current = current->left;//下一指针指向当前指针的左端      index++;//下标后加加      }   if (index==k)//当前元素即为第k个元素   {x = current->data; return true;}   return false; }template<class T>int DoubleCircular<T>::Search(const T& x) const//返回元素x在表中的位置;如果x不在表中,则返回0{   if (!rightEnd) return 0;  //链表为空   DoubleNode<T> *current = rightEnd->left;//当前指针指向最右端节点的左   int index = 1;//标记下标为1    while ( current != rightEnd&& current->data != x) //当当前指针不是最右端节点且指向的值与x的值不同时   {      current = current->left;//下一指针指向当前指针的左端      index++; }   if (current->data == x)//当当前指针指向的值与x的值相同时    return index;   return 0;}template<class T>DoubleCircular<T>& DoubleCircular<T>::Delete(int k, T& x)//删除表中第k个元素,并把它保存到x中,函数返回修改后的线性表{   if (k<1||!rightEnd) throw OutOfBounds();//k无意义或者链表为空时抛出异常   DoubleNode<T> *p =rightEnd->left;//p指针指向最右端节点的左   int index = 1;//标记下标为1     for (; index<k && p!=rightEnd; index++)      p = p->left;//p指向p的左   if (index != k) throw OutOfBounds(); // 当下标与k不同时抛出异常   //删除k   p->left->right = p->right;   p->right->left = p->left;//   x = p->data;//将p指向的数据赋值给x   if (p == rightEnd)  //当p恰巧最右端节点时       if (k == 1)  // 新的表是空的         rightEnd = 0;      else // 不空        rightEnd=rightEnd->right;//将最右端节点的右赋值给最右端节点   delete p;//释放   return *this;}template <class T>DoubleCircular<T>& DoubleCircular<T>::Insert(int k, const T& x)//在第k个元素之后插入x,函数返回修改后的线性表{   if (k < 0) throw OutOfBounds();//k无意义时抛出异常   if (k) {      if (!rightEnd) throw OutOfBounds();  // 空表时抛出异常      DoubleNode<T> *p =rightEnd->left;//p指针指向最右端节点的左      int index = 1;//标记下标为1       for (; index < k && p != rightEnd;             index++)           p = p->left;//p指向p的左      if (index != k) throw OutOfBounds();// 当下标与k不同时抛出异常 //在第k个元素后插入x      DoubleNode<T> *y = new DoubleNode<T>;      y->data = x;      y->left = p->left;      y->left->right = y;      p->left = y;      y->right = p;      if (p ==rightEnd)    rightEnd= y;      }   else {//作为第一个插入         DoubleNode<T> *y = new DoubleNode<T>;         y->data = x;         if (rightEnd) {            y->left = rightEnd->left;            y->left->right = y;           rightEnd->left = y;            y->right = rightEnd;            }         else {//空表               rightEnd= y;               y->right = y;               y->left = y;               }         }   return *this;}//输出template<class T>void DoubleCircular<T>::Output(ostream& out) const{   if (!rightEnd) return;   DoubleNode<T> *current;   for (current = rightEnd->left; current != rightEnd;                         current = current->left)      out << current->data << "  ";  out << current->data << "  ";}// 重载<<template <class T>ostream& operator<<(ostream& out, const DoubleCircular<T>& x)   {x.Output(out); return out;} //DoubleCircle.cpp#include<iostream>#include"DoubleCircular.h"using namespace std;void main(void){      DoubleCircular<int> L;      cout << "Length = " << L.Length() << endl;      cout << "IsEmpty = " << L.IsEmpty() << endl;   L.Insert(0,4).Insert(1,5).Insert(2,1).Insert(3,3).Insert(4,9).Insert(5,7);   L.Insert(1,6).Insert(3,8).Insert(5,2);      cout << "新建的链表为 " << L << endl;   cout<<"Length = "<<L.Length()<<endl;      cout << "IsEmpty = " << L.IsEmpty() << endl;   cout<<"链表中值为3的位置: "<<L.Search(3)<<endl;      int z;   //      L.Find(3,z);      cout << "第三个元素为:" << z << endl;   //      cout << "9的位置为:" << L.Search(9) << endl;   //        int a1,a2,a3;   L.Delete(5,a1).Delete(1,a2).Delete(3,a3);      cout << "删除的元素是: " << a1           << "  " << a2 << "  " << a3 << endl;      cout << "新的链表为 :" << L << endl;      L.Delete(1,a1).Delete(1,a2);      cout << "删除的元素是:" << a1           << "  " << a2 << endl;      cout << "新的链表为: " << L << endl;  } 

原创粉丝点击