【算法与数据结构】双循环链表C++实现
代码清单
DCList.h
/*----------------------------【Specification】----------------------------
Coding: UTF-8
Solution:【数据结构之双循环链表实现】
IDE:Visual Studio Code + CMake
2020年11月13日 CREATED BY 一箭双雕
-------------------------------------------------------------------------*/
#ifndef _DCLIST_
#define _DCLIST_
#include<iostream>
#include<malloc.h>
#include<assert.h>
using namespace std;
template<typename ElemType>class ListNode //带模板结点类
{
public:
ElemType date; //结点数据类型
ListNode<ElemType>* prio; //结点前驱指针
ListNode<ElemType>* next; //结点后继指针
};
template<typename ElemType>class DCList :public ListNode<ElemType> //带模板并继承ListNode的链表类
{
public:
ListNode<ElemType>* Head; //头结点
public:
DCList(); //默认构造函数
~DCList(); //析构函数
void InsertVal(const ElemType key); //按值插入
bool InsertPos(const DCList<ElemType> &list,const ElemType key, int pos); //按位插入
bool Reverse(const DCList<ElemType> &list); //逆置链表
bool Sort(const DCList<ElemType> &list); //链表排序
void PushBack(const ElemType date); //尾插数据
void PushFront(const ElemType date); //头插数据
void PopBack() const; //链表尾删数据
bool PopVal(const DCList<ElemType> &list, const ElemType key); //按值删除(递归删除)
bool PopPos(const DCList<ElemType> &list, const int pos); //按位删除
void PopFront() const; //链表头删数据
void ShowList() const; //打印链表
int length() const; //求链表长度
void ClearDCList() const; //重置链表为空
};
template<typename ElemType>
DCList<ElemType>::DCList() //构造一个空线性表
{
Head = new ListNode<ElemType>; //产生头结点
assert(Head != nullptr); //存储分配失败退出
Head->next = Head->prio = Head; //链表双循环特性
}
template<typename ElemType>
DCList<ElemType>::~DCList() //摧毁线性表
{
ClearDCList(); //置为空表
delete Head; //释放头结点
}
template<typename ElemType>
void DCList<ElemType>::ClearDCList()const //清除链表
{
ListNode<ElemType>* p;
while (Head->next != Head)
{
p = Head->next;
p->next->prio = p->prio;
p->prio->next = p->next;
free(p);
}
}
template<typename ElemType>
void DCList<ElemType>::PushBack(const ElemType date) //链表尾插数据
{
ListNode<ElemType>* s = new ListNode<ElemType>;
s->date = date;
ListNode<ElemType>* p = Head;
while (p->next != Head)
{
p = p->next;
}
s->next = p->next;
s->prio = p;
p->next->prio = s;
p->next = s;
}
template<typename ElemType>
void DCList<ElemType>::ShowList()const //打印链表
{
ListNode<ElemType>* p = Head->next;
while (p != Head)
{
cout << p->date << "-->";
p = p->next;
}
cout << "Nul." << endl;
}
template<typename ElemType>
int DCList<ElemType>::length()const //求链表长度
{
ListNode<ElemType> *p = Head->next;
int k = 0; //记录遍历次数
while (p!=Head)
{
p = p->next;
k++;
}
return k;
}
template<typename ElemType>
void DCList<ElemType>::PushFront(const ElemType date) //链表头插数据
{
ListNode<ElemType>* s = new ListNode<ElemType>;
s->date = date;
ListNode<ElemType> *p = Head->next;
if(p==Head)
{
PushBack(date);
return;
}
s->next = p;
s->prio = p->prio;
p->prio->next = s;
p->prio = s;
}
template<typename ElemType>
void DCList<ElemType>::PopBack()const //链表尾删数据
{
ListNode<ElemType> *p = Head->next;
if(p==Head)
{
cout << "链表已空" << endl;
return;
}
while(p->next!=Head)
{
p = p->next;
}
p->prio->next = Head;
p->next->prio = p->prio;
free(p);
}
template<typename ElemType>
void DCList<ElemType>::PopFront()const //链表头删数据
{
ListNode<ElemType> *p = Head->next;
if(p==Head)
{
cout << "链表已空" << endl;
return;
}
p->prio->next = p->next;
p->next->prio = p->prio;
free(p);
}
template<typename ElemType>
void DCList<ElemType>::InsertVal(const ElemType key) //按值插入
{
ListNode<ElemType>* s = new ListNode<ElemType>;
ListNode<ElemType> *p = Head->next;
s->date = key;
while (p!=Head && p->date<s->date)
{
p = p->next;
}
s->next = p;
s->prio = p->prio;
p->prio->next = s;
p->prio = s;
}
template<typename ElemType>
bool DCList<ElemType>::InsertPos(const DCList<ElemType> &list, const ElemType key,int pos) //按位插入
{
if (pos<0 || pos>list.length())
return false;
ListNode<ElemType> *s = new ListNode<ElemType>;
ListNode<ElemType> *p = Head->next;
s->date = key;
for (int i = 0; i < pos; i++)
{
p = p->next;
}
s->next = p;
s->prio = p->prio;
p->prio->next = s;
p->prio = s;
return true;
}
template<typename ElemType>
bool DCList<ElemType>::Reverse(const DCList<ElemType> &list) //逆置链表
{
if (list.length()==0 || list.length()==1)
return false;
ListNode<ElemType> *r, *q, *p = Head->next;
q = p->next;
p->next = Head;
Head->prio = p;
while (q!=Head)
{
r = Head->next;
p = q;
q = p->next;
p->next = r;
r->prio->next = p;
p->prio = r->prio;
r->prio = p;
}
return true;
}
template<typename ElemType>
bool DCList<ElemType>::Sort(const DCList<ElemType> &list) //自动排序
{
if (list.length()==0 || list.length()==1)
return false;
ListNode<ElemType> *r, *q, *p = Head->next;
q = p->next;
p->next = Head;
p->next->prio = p;
while (q!=Head)
{
r = Head;
p = q;
q = p->next;
while (r->next!=Head && p->date>r->next->date)
{
r = r->next;
}
p->next = r->next;
r->next->prio = p;
r->next = p;
p->prio = r;
}
return true;
}
template<typename ElemType>
bool DCList<ElemType>::PopVal(const DCList<ElemType> &list, const ElemType key) //按值删除(递归删除)
{
ListNode<ElemType> *p = Head->next;
while (p!=Head && p->date!=key)
{
p = p->next;
}
if (p==Head)
{
return false;
}
else
{
p->prio->next = p->next;
p->next->prio = p->prio;
free(p);
if(this->PopVal(list,key))
return true;
}
return true;
}
template<typename ElemType>
bool DCList<ElemType>::PopPos(const DCList<ElemType> &list, const int pos) //按位删除
{
if (pos<0 || pos>list.length())
return false;
ListNode<ElemType> *p = Head;
for (int i = 0; i < pos; i++)
{
p = p->next;
}
p->prio->next = p->next;
p->next->prio = p->prio;
free(p);
return true;
}
#endif
DCList.cpp
#include"DCList.h"
int main()
{
DCList<int> mylist; //链表实例化
int select = 1; //保存功能选择开关
int pos = 0; //保存数据位置
int leng = 0; //保存链表长度
int date = 0; //保存输入数据(可自定义修改类型)
while (select!=0)
{
cout << " 双循环链表测试程序 " << endl;
cout << "**********************************" << endl;
cout << "* [1]头插数据 [2]尾插数据 *" << endl;
cout << "* [3]头部删除 [4]尾部删除 *" << endl;
cout << "* [5]按位插入 [6]按值插入 *" << endl;
cout << "* [7]逆置链表 [8]自动排序 *" << endl;
cout << "* [9]按值删除 [10]按位删除 *" << endl;
cout << "**********************************" << endl;
cout << "目前缓存链表为:";
mylist.ShowList();
leng = mylist.length();
cout << "目前链表长度为:" << leng <<"\n"<< endl;
cout << "功能选择(标*为待开发项)>>>>";
switch (cin >> select,select)
{
case 1:
cout << "请输入头部插入的数据(-1结束)>>>>";
while(cin >> date,date!=-1)
{
mylist.PushFront(date);
}
break;
case 2:
cout << "请输入尾部插入的数据(-1结束)>>>>";
while(cin >> date,date!=-1)
{
mylist.PushBack(date);
}
break;
case 3:
mylist.PopFront();
break;
case 4:
mylist.PopBack();
break;
case 5:
cout << "请输入要插入的数据>>>>";
cin >> date;
cout << "请输入要插入的位置>>>>";
cin >> pos;
mylist.InsertPos(mylist, date, pos);
break;
case 6:
cout << "请输入要插入的值>>>>";
cin >> date;
mylist.InsertVal(date);
break;
case 7:
mylist.Reverse(mylist);
break;
case 8:
mylist.Sort(mylist);
break;
case 9:
cout << "请输入要删除的值>>>>";
cin >> date;
if(!mylist.PopVal(mylist, date))
cout << "删除失败";
break;
case 10:
cout << "请输入要删除的位置>>>>";
cin >> pos;
if(!mylist.PopPos(mylist, pos))
cout << "删除失败";
break;
default:
cout << "选择错误!" << endl;
break;
}
system("cls");
}
}
源代码下载(VScode+CMake)https://github.com/yijianshuangdiao/BISAICESHI_DCList