双向循环链表模板类(C++)
双向链表又称为双链表,使用双向链表的目的是为了解决在链表中访问直接前驱和后继的问题。其设置前驱后继指针的目的,就是为了节省其时间开销,也就是用空间换时间。
在双向链表的每个节点中应有两个链接指针作为它的数据成员:pred指向其前驱节点,next指向其后继节点。再加上数据域,因此每个双向链表至少包括三个域。


实现代码如下
//header.h
#include<iostream>
using namespace std;
/*
* 双向循环链表头文件,
* 其声明中封装有指向链表附加头节点的头x指针first
*/ template<class T>
struct DbNode
{
T data;
DbNode<T> *pred, *next;
DbNode(T value, DbNode<T> *a = NULL, DbNode<T> *b = NULL):\
data(value), pred(a), next(b){}
DbNode(DbNode<T> *a = NULL, DbNode<T> *b = NULL):pred(a), next(b){}
}; template<class T>
class Dblist
{
private: DbNode<T> *first;
public:
Dblist(T value);
~Dblist(){makeEmpty();}
void makeEmpty();
int Length()const;
bool IsEmpty(){return (this->first->pred == this->pred);}
DbNode<T> *getHead()const{return this->first;}
DbNode<T> *Locate(int i, int d);
DbNode<T> *Search(const T& x);
bool Insert(int i, const T& x, int d);
bool Remove(int i, T& x, int d);
void Print(int d);
};
template<class T>
int Dblist<T>::Length()const
{
DbNode<T> *tmp = this->first;
int i = 1;
while(tmp->next!=this->first)
{
++i;
tmp = tmp->next;
}
return i;
}
template<class T>
bool Dblist<T>::Remove(int i, T& x, int d)
{
DbNode<T> *p = this->Locate(i, d);
if(!p)
return false;
x = p->data;
if(p==this->first && this->Length()>1)
this->first = p->next;
else
cout<<"仅有头节点的双向循环链表已被删除!请勿在没添加新元素前对其调用。"<<endl;
p->pred->next = p->next;
p->next->pred = p->pred;
delete p;
return true;
}
template<class T>
DbNode<T>* Dblist<T>::Search(const T& x)
{
DbNode<T> *tmp = this->first;
do
{
if(tmp->data==x)
{
cout<<"address of x is "<<tmp<<" x = "<<tmp->data<<endl;
return tmp;
}
tmp = tmp->pred;
}while(tmp!=this->first);
return NULL;
}
template<class T>//定位元素,d=0时从头节点向前(pred)查第i个元素,d!=0时,从头节点向后(next)找第i个元素
DbNode<T>* Dblist<T>::Locate(int i, int d)
{
if(this->first->next==this->first || i==0)
return this->first;
int t = 1;
DbNode<T>* tmp = this->first;
if(d) //向后找
{
while(tmp->next!=this->first && t!=i)//查找到的条件为,在没把双向循环链表遍历一遍前,t=i
{
tmp = tmp->next;
++t;
}
if(tmp->next==this->first&&t!=i)
return NULL;
else
return tmp; }
else //向前找
{
while(tmp->pred!=this->first && t!=i)
{
tmp = tmp->pred;
++t;
}
if(tmp->pred==this->first&&t!=i)
return NULL;
else
return tmp;
}
}
template<class T>
bool Dblist<T>::Insert(int i, const T& x, int d)
{
DbNode<T> *p = this->Locate(i, d);
if(!p)
return false;
DbNode<T> *newnode = new DbNode<T>;
if(newnode==NULL)
{
cout<<"申请内存错误!"<<endl;
exit(1);
}
newnode->data = x;
if(d) //p节点后插入
{
p->next->pred = newnode;
newnode->pred = p;
newnode->next = p->next;
p->next = newnode;
}
else //p节点前插入
{
p->pred->next = newnode;
newnode->next = p;
newnode->pred = p->pred;
p->pred = newnode;
}
return true;
}
template<class T>
void Dblist<T>::makeEmpty()
{
DbNode<T> *p, *q = this->first->pred;
while(q != this->first)
{
p = q;
q = q->pred;
delete p;
}
}
template<class T>
void Dblist<T>::Print(int d)
{
if(d) //正序打印
{
cout<<"Positive order: ";
DbNode<T> *tmp = this->first;
while(tmp->next != this->first)
{
cout<<tmp->data<<"->";
tmp = tmp->next;
}
cout<<tmp->data<<"->over."<<endl; }
else //逆序打印
{
DbNode<T> *tmp = this->first;
cout<<"Reverse sequence: ";
while(tmp->pred != this->first)
{
cout<<tmp->data<<"->";
tmp = tmp->pred;
}
cout<<tmp->data<<"->over."<<endl;
}
} template<class T>
Dblist<T>::Dblist(T value)
{
this->first = new DbNode<T>(value);
if(this->first == NULL)
{
cerr<<"内存分配错误!"<<endl;
exit(1);
}
this->first->next = this->first->pred = this->first;
}
//main.cpp
#include"header.h" int main()
{
Dblist<int> dl(888);
dl.Print(0);
for(int i=1; i<=4; ++i)
{
dl.Insert(1, i, 0);
}
dl.Print(1);
int l = 999, k = 0;
dl.Insert(0, l, 0);
//int k = 0;
dl.Print(1);
dl.Remove(0, k, 0);
dl.Print(1);
k = 5;
dl.Search(k);
dl.Print(0);
return 0;
}
完成效果

双向循环链表模板类(C++)的更多相关文章
- Linux内核中的通用双向循环链表
开发中接触Linux越来越多,休息放松之余,免不了翻看翻看神秘的Linux的内核.看到双向链表时,觉得挺有意思的,此文记下. 作为众多基础数据结构中的一员,双向循环链表在各种“教科书”中的实现是相当的 ...
- C++实现双向循环链表
本次博文是关于利用C++模板的方式实现的双向循环链表以及双向循环链表的基本操作,在之前的博文C++语言实现双向链表中,已经给大家分析了双向循环链表的结构,并以图示的方式给大家解释了双向循环链表的基本操 ...
- 双向循环链表的Java版本实现
1.单项循环列表 单向循环链表是单链表的另一种形式,其结构特点是链表中最后一个结点的指针不再是结束标记,而是指向整个链表的第一个结点,从而使单链表形成一个环.和单链表相比,循环单链表的长处是从链尾到链 ...
- java与数据结构(4)---java实现双向循环链表
线性表之链式存储结构双向循环链表 双向循环链表:每个结点包含了数据.直接前驱地址指针和直接后驱地址指针,头结点的直接前驱指向尾结点,尾结点的直接后驱指向头结点,头尾相连构成一个可正可反的圆环.可以形象 ...
- python实现 双向循环链表
最近身边的朋友在研究用python来实现数据结构.遇到一个问题就是双向循环链表的实现,改指向的时候总是发蒙. 我自己尝实现了一个python的双向循环链表.附上代码,希望对大家有帮助. 如果不懂什么是 ...
- "《算法导论》之‘线性表’":双向循环链表
本文双链表介绍部分参考自博文数组.单链表和双链表介绍 以及 双向链表的C/C++/Java实现. 1 双链表介绍 双向链表(双链表)是链表的一种.和单链表一样,双链表也是由节点组成,它的每个数据结点中 ...
- java实现双向循环链表
java实现循环链表:http://www.cnblogs.com/lixiaolun/p/4643911.html 在单链表中,查询下一个元素的时间是O(1).查询上一个元素的时间却是O(n). 为 ...
- Linux内核2.6.14源码分析-双向循环链表代码分析(巨详细)
Linux内核源码分析-链表代码分析 分析人:余旭 分析时间:2005年11月17日星期四 11:40:10 AM 雨 温度:10-11度 编号:1-4 类别:准备工作 Email:yuxu97101 ...
- 数据结构8: 双向链表(双向循环链表)的建立及C语言实现
之前接触到的链表都只有一个指针,指向直接后继,整个链表只能单方向从表头访问到表尾,这种结构的链表统称为 “单向链表”或“单链表”. 如果算法中需要频繁地找某结点的前趋结点,单链表的解决方式是遍历整个链 ...
随机推荐
- oeasy教您玩转vim - 57 - # 行可视化
可视化编辑 回忆上节课内容 上次我们了解到可视模式 其实可视化对应三种子模式 字符可视模式 v 行可视模式 大写V 块可视模式ctrl+v 我们先来了解字符可视化模式 快捷键 v 可配合各种mot ...
- Python3 装逼神器---词云(wordcloud)
词云 (Word Cloud)是对文本中出现频率较高的词语给予视觉化展示的图形, 是一种常见的文本挖掘的方法. 实例: 依赖包: # pip3 install wordcloud jieba ...
- Qt Creator打造VScode one dark pro主题配色
1.缘由 我之前习惯使用 vscode 进行开发,对 vscode 的 one dark pro 主题情有独钟.无奈公司需要使用 Qt Creator 进行日常开发,只能暂时舍弃 vscode,采用曲 ...
- PHP怎样写延时队列(定时器)
背景 PHP没有定时器,依托的都是crontab这样的系统工具,也没有go中defer这样的延时方法,本文介绍几种PHP写延时队列的几种姿势. 延时队列的定义 普通的队列是先进先出,但是延时队列并不是 ...
- 使用getopt 解析参数
getopt被用来解析命令行选项参数. #include <unistd.h> extern char *optarg; //选项的参数指针 extern int optind, //下一 ...
- fiddler 手机+浏览器 抓包
用fiddler对手机上的程序进行抓包 前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在同一wi ...
- js中的特数值-null-undefined-NaN
一.补充 1.js中的三大特殊数据:undefined.null.NaN NaN :非法的数值运算得到的结果 特殊之处: 是一个数值型数据,但不是一个数字 NaN不等于任何值,和任何数据都不相等,Na ...
- jQuery css()选择器使用说明
css选择器只是jquery中的一个功能罢了,下面我来给各位朋友详细介绍jQuery css()选择器使用方法与说明详解,有需要了解学习的同学可参考. CSS操作有一个重要的方法:CSS() CSS( ...
- CAP 5.2 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 5.2 版本正式版,在这个版本中,我们主要致力于更好的优化使用体验以及支持新的 Transport,同时在该版本也进行了一些 bug 修复的工作. 自从 5. ...
- [atARC124F]Chance Meeting
为了方便,不妨先将$n$和$m$都减小1,其意义即为移动的次数 注意到老鼠向下移动和猫向上移动对于第2个条件是等价的,对于第1个条件即要求都恰好移动$n$次,那么对应的方案数即为${2n\choose ...