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; }