【C++数据结构】模版类实现双循环链表的基本操作
2015-08-23 16:29
911 查看
单链表结构为我们提供方便分数据插入和删除工作,美中不足的是查询数据不方便,对于单链表查找数据至少要遍历一边. 为此我们提出双链表结构,从而方便的查询数据.
给出双链表的一般结构:
一种是带头结点(哨兵位)的管理方式,另一种是带管理节点管理方式。 但是我们不建议采用管理节点和头结点并存的方式(管理较前两者复杂)。
提供带头结点的双循环链表模版类实现,代码如下:
头文件:
测试代码:
函数的调用与引用关系如下:
运行环境:VS2015
给出双链表的一般结构:
一种是带头结点(哨兵位)的管理方式,另一种是带管理节点管理方式。 但是我们不建议采用管理节点和头结点并存的方式(管理较前两者复杂)。
提供带头结点的双循环链表模版类实现,代码如下:
头文件:
#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: //error cout << "请输入要删除的数:> " << 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
相关文章推荐
- c++实现数据结构1.顺序表
- 数据结构_链表_单向链表
- 数据结构_链表_单向链表
- 浅谈算法和数据结构: 九 平衡查找树之红黑树
- 数据结构_队列
- 数据结构_队列
- Linux内核工程导论——数据结构:树
- 数据结构之队列的顺序实现
- 数据结构之栈的链表实现
- 【算法结构】一些经典的算法和数据结构的问题
- 数据结构之栈的顺序表实现
- uva 11995 基础数据结构的模拟
- 数据结构之链表
- 数据结构之顺序表
- 数据结构——树
- 深入剖析 redis 数据结构 skiplist
- XMUT acdream 数据结构专场 C题(单调栈)
- C++数据结构之Queue(队列)
- 【水题】统计数字
- HDU_1394 Minimum Inversion Number(线段树)