【算法与数据结构】双循环链表C++实现

【算法与数据结构】双循环链表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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值