【C++数据结构】模版类实现双循环链表的基本操作

来源:互联网 发布:海康网络球机接线图 编辑:程序博客网 时间:2024/06/05 19:11

单链表结构为我们提供方便分数据插入和删除工作,美中不足的是查询数据不方便,对于单链表查找数据至少要遍历一边.  为此我们提出双链表结构,从而方便的查询数据.


给出双链表的一般结构:




一种是带头结点(哨兵位)的管理方式,另一种是带管理节点管理方式。 但是我们不建议采用管理节点和头结点并存的方式(管理较前两者复杂)。



提供带头结点的双循环链表模版类实现,代码如下:


头文件:

#pragma once#include<iostream>  using namespace std;template<class _T>class DCList{protected:struct Node;friend struct Node;typedef _T* _ptr;typedef Node* _NodePtr;struct Node{_NodePtr _Prev;_NodePtr _Next;_T _Value;};private:size_t Size;_NodePtr Handle;public:DCList() :Size(0), Handle(_BuyNode()){}~DCList(){clear();_FreeNode(Handle);Size = 0;}public:bool IsEmpty(){return Size == 0;}size_t length(){return Size;}_NodePtr& begin(){return Handle->_Next;}_NodePtr& end(){return Handle;}void Insert(_NodePtr _P, const _T& v){_NodePtr _S = _BuyNode(_P, _P->_Prev);_P->_Prev = _S;_S->_Prev->_Next = _S;_S->_Value = v;++Size;}bool Insert_val(const _T& x){_NodePtr _P = _BuyNode(NULL,NULL,x);Insert_val(_P);return true;}void Insert(_NodePtr _P, _NodePtr _S){_S->_Next = _P->_Next;_P->_Next->_Prev = _S;_P->_Next = _S;_S->_Prev = _P;if (_P == Handle->_Prev){_S->_Next = Handle;Handle->_Prev = _S;}Size++;}void Insert_val(_NodePtr _Cur){_NodePtr _P = Handle;while (_P->_Next != end()  && _Cur->_Value > _P->_Next->_Value)_P = _P->_Next;Insert(_P, _Cur);}void push_back(const _T& x){Insert(end(), x);}void push_front(const _T& x){Insert(begin(), x);}void ShowList(){if (IsEmpty()){cout << "null" << endl;return;}_NodePtr cur = begin();while (cur != end()){cout << cur->_Value << "->";cur = cur->_Next;}cout << "null" << endl;}void erase(_NodePtr _P)  //删除自己{if (IsEmpty())return;if (  _P != Handle && _P != NULL){_P->_Prev->_Next = _P->_Next;_P->_Next->_Prev = _P->_Prev;_P->_Prev = _P->_Next = NULL;}Size--;_FreeNode(_P);}void pop_back(){erase(Handle->_Prev);}void pop_front(){erase(Handle->_Next);}_NodePtr& find(const _T v){_NodePtr _Cur = begin();while (_Cur != end()){if (_Cur->_Value == v)return _Cur;}cout << "无此节点,返回头" << endl;return Handle;}void delete_value(const _T _V){_NodePtr p;while (p = find(_V), p != end()){erase(p);}}_T& findBypos(size_t pos){if (pos > Size){cout << "多走 "<< pos/Size<<"圈" << endl;pos %= Size;}_NodePtr p = begin();while (p !=end() && pos-1){p = p->_Next;pos--;}return p->_Value;}void clear(){while (!IsEmpty())pop_front();}void destroy(){clear();_FreeNode(Handle);Handle = NULL;}void merge(DCList& r){_NodePtr p = r.begin();_NodePtr q;r.Handle->_Next = NULL;p->_Prev = NULL;while (p->_Next !=NULL){q = p;p = p->_Next;q->_Next = NULL;p->_Prev = NULL;Insert_val(q);r.Size--;}r.begin() = r.end();}void sort(){if (length() <= 1)return;_NodePtr _P = begin()->_Next;_NodePtr _Q;begin()->_Next->_Prev = NULL;begin()->_Next = Handle;Handle->_Prev = begin();Size = 1;while (_P != end()){_Q = _P;_P = _P->_Next;_Q->_Next = NULL;_P->_Prev = NULL;Insert_val(_Q);}}void resver(){if (length() <= 1)return;_NodePtr _P = begin()->_Next;_NodePtr _Q;begin()->_Next->_Prev = NULL;begin()->_Next = Handle;Handle->_Prev = begin();Size = 1;while (_P != end()){_Q = _P;_P = _P->_Next;_Q->_Next = NULL;_P->_Prev = NULL;begin()->_Prev = _Q;_Q->_Next = begin();Handle->_Next = _Q;_Q->_Prev = Handle;}}protected:_NodePtr _BuyNode(_NodePtr _Narg = NULL, _NodePtr _Parg = NULL, _T v = 0){_NodePtr _S = new Node;_S->_Next = _Narg != 0 ? _Narg : _S;_S->_Prev = _Parg != 0 ? _Parg : _S;_S->_Value = v;return (_S);}void _FreeNode(_NodePtr _P){delete _P;_P = NULL;}};

测试代码:


#include<iostream>  #include "DCList.h"using namespace std;void main(){DCList<int> mylist;size_t select = 1;int item = 0;size_t pos = 0;while (select){cout << "************************************" << endl;cout << "* [0]  quit_system [1] push_back   *" << endl;cout << "* [2]  push_front  [3] show_seqlist*" << endl;cout << "* [4]  pop_back    [5] pop_front   *" << endl;cout << "* [6]  insert_val  [7] delete_val  *" << endl;cout << "* [8]  find        [9]  merge      *" << endl;cout << "* [10] sort       [11] clear       *" << endl;cout << "* [12] destroy    [13] length      *" << endl;cout << "* [14] resver     [15] next        *" << endl;cout << "* [16] prio                        *" << endl;cout << "************************************" << endl;cout << "请选择:>";cin >> select;system("cls");switch (select){case 1:cout << "请输入要插入的数据(-1结束):>";while (cin >> item, item != -1){mylist.push_back(item);}break;case 2:cout << "请输入要插入的数据(-1结束):>";while (cin >> item, item != -1){mylist.push_front(item);}break;case 3:mylist.ShowList();break;case 4:mylist.pop_back();break;case 5:mylist.pop_front();break;case 6:cout << "请输入要插入的数:> " << endl;cin >> item;mylist.Insert_val(item);break;case 7://errorcout << "请输入要删除的数:> " << endl;cin >> item;mylist.delete_value(item);break;case 8:cout << "请输入要查询的位置:> " << endl;cin >> pos;cout << mylist.findBypos(pos) << endl;break;case 11:cout << "链表将被清空:> " << endl;mylist.clear();break;case 12:cout << "链表将被摧毁:> " << endl;mylist.destroy();break;case 13:cout<<"长度为:> "<<mylist.length()<<endl;break;case 14:cout << "链表将被逆置 ! " << endl;//mylist.resver();mylist.ShowList();break;default:break;}}}


函数的调用与引用关系如下:


运行环境:VS2015




4 0