北邮22信通:复习补充:双向链表的实现

这篇具有很好参考价值的文章主要介绍了北邮22信通:复习补充:双向链表的实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

北邮22信通一枚~   

跟随课程进度每周更新数据结构与算法的代码和文章 

持续关注作者  解锁更多邮苑信通专属代码~

获取更多文章  请访问专栏:

北邮22信通_青山如墨雨如画的博客-CSDN博客

**说明**

最近复习看到书后有双向链表的题目,编出来供大家复习~

*********

目录

一.讲解

1.insert 增添函数

2.构造函数:

3.del删除函数:

4.change修改函数

5.search查找函数

二.代码部分及运行结果

完整代码

代码效果图:

运行结果:


 文章来源地址https://www.toymoban.com/news/detail-465589.html

一.讲解

小编实现的这个双向链表只涉及增删改查四个功能。下面先大体说一下思路。

结点结构包括数据域、左指针和右指针 ,左指针链接左边的相邻结点,右指针链接右边的相邻结点;

双向链表类的实现部分,成员属性包括整条链表的头指针和尾指针以及链表的长度;

为什么增添了尾指针,请读者带着问题先往下看;

成员函数包括类的构造函数和析构函数,增删改查4种功能的实现函数以及链表打印函数,下面逐个讲解这几个函数。

1.insert 增添函数

实现增添功能的过程如下图所示;

北邮22信通:复习补充:双向链表的实现

简单讲解一下插入过程的步骤:

首先申请一个temp大小的堆空间,用来存放新增结点;

初始化这个结点,数据域赋值为传入的参数,两个指针域均赋值为空指针;

找到插入的地方,比如传入的参数是3那就是找到第3个结点;

新增结点的右指针和第3个结点相连, 

新增结点的左指针和第三个结点的前驱结点也就是第二个结点相连

(先将新增结点的两个指针连在链表上,

然后再断开原先链表的指针连接,并重新与新增链表相连);

断开前驱结点的右指针,将右指针和新增结点相连,

断开查找结点的左指针,将左指针与新增结点相连;执行完毕。

insert函数的代码:

template<class temp>
void linklist<temp>::insert(int i, temp x)
{
	node<temp>* p = this->front->right;
	while (--i)
		p = p->right;
	node<temp>* before_p = p->left;
	node<temp>* s = new node<temp>;
	s->data = x;
	s->right = p;
	s->left = before_p;
	p->left = s;
	before_p->right = s;
	this->length++;
}

2.构造函数:

        这里将讲解为什么要多引入一个尾指针成员属性

        其实构造函数无非就是数据的接连插入操作,所以我们完全可以调用insert函数来实现构造函数的头插法。但是面临的问题是,如上insert函数的实现过程,我们必须保证至少有两个结点,才能执行在这两个结点之间的插入操作。综上,新增尾指针。其实,不添加尾指针也可以实现构造函数,即如果链表中只存在头结点,则将新增结点直接接在头结点后面,以后再新增数据,就直接调用insert函数实现。但是增加了尾指针还有其他好处比如倒序遍历,使得某些方法变得更加简便。所以小编选择增加了一个链表尾指针的成员属性。

构造函数实现如下:

template<class temp>
linklist<temp>::linklist(temp a[], int n)
{
	this->front = new node<temp>;
	this->rear = new node<temp>;
	this->front->left = NULL;
	this->front->right = this->rear;
	this->rear->left = this->front;
	this->rear->right = NULL;
	this->length = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		insert(1, a[i]);
		this->length++;
	}
}

3.del删除函数:

删除操作的大致思路如下:

        找到要删除的结点,其前驱结点的右指针指向删除结点的后继结点,后继结点的左指针指向删除结点的前驱结点,最后删除要删除的结点,执行完毕。

实现过程如下:

template<class temp>
temp linklist<temp>::del(int i)
{
	if (i > this->length)
		throw"上溢!";
	node<temp>* p = this->front->right;
	while (--i)
		p = p->right;
	cout << "被删除的数据为:";
	p->data.print();
	p->left->right = p->right;
	p->right->left = p->left;
	temp tempdata = p->data;
	return tempdata;
}

4.change修改函数

很简单,向单链表一样循环,找到要修改数据域的结点,修改数据域即可。

5.search查找函数

思路同上。

二.代码部分及运行结果

完整代码

#include<iostream>
using namespace std;
class student
{
private:
	int ID;
	string name;
public:
	student()
	{
		this->ID = 0;
		this->name = "nuknown_name";
	}
	student(int ID, string name)
	{
		this->ID = ID;
		this->name = name;
	}
	void print()
	{
		cout << this->ID << " " << this->name << endl;
	}
	friend ostream& operator <<(ostream& output, student& s)
	{
		output << s.ID << " " << s.name << endl;
		return output;
	}
	bool operator !=(student&s)
	{
		return (this->ID != s.ID) || (this->name != s.name) ? true : false;
	}
};

template<class temp>
struct node                                                                                                                                         
{
	temp data;
	node* left;
	node* right;
};

template<class temp>
class linklist
{
private:
	node<temp>* front;
	node<temp>* rear;
	int length;
public:
	linklist()
	{
		this->front = new node<temp>;
		this->rear = new node<temp>;
		this->front->left = NULL;
		this->front->right = this->rear;
		this->rear->left = this->front;
		this->rear->right = NULL;
		this->length = 0;
	}
	linklist(temp a[], int n);
	~linklist();
	void insert(int i, temp x);
	temp del(int i);
	void change(int i, temp x);
	void search(temp x);
	void printlist();
};

template<class temp>
linklist<temp>::linklist(temp a[], int n)
{
	this->front = new node<temp>;
	this->rear = new node<temp>;
	this->front->left = NULL;
	this->front->right = this->rear;
	this->rear->left = this->front;
	this->rear->right = NULL;
	this->length = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		insert(1, a[i]);
		this->length++;
	}
}

template<class temp>
linklist<temp>::~linklist()
{
	node<temp>* p = this->front;
	while (p != NULL)
	{
		this->front = p;
		p = p->right;
		delete front;
	}
}

template<class temp>
void linklist<temp>::insert(int i, temp x)
{
	node<temp>* p = this->front->right;
	while (--i)
		p = p->right;
	node<temp>* before_p = p->left;
	node<temp>* s = new node<temp>;
	s->data = x;
	s->right = p;
	s->left = before_p;
	p->left = s;
	before_p->right = s;
	this->length++;
}

template<class temp>
temp linklist<temp>::del(int i)
{
	if (i > this->length)
		throw"上溢!";
	node<temp>* p = this->front->right;
	while (--i)
		p = p->right;
	cout << "被删除的数据为:";
	p->data.print();
	p->left->right = p->right;
	p->right->left = p->left;
	temp tempdata = p->data;
	return tempdata;
}

template<class temp>
void linklist<temp>::change(int i, temp x)
{
	if (i > this->length)
		throw "上溢!";
	node<temp>* p = this->front->right;
	while (--i)
		p = p->right;
	if (p->right == NULL)
	{
		cout << "未查询到数据!" << endl;
		return;
	}
	p->data = x;

}

template<class temp>
void linklist<temp>::search(temp x)
{
	node<temp>* p = this->front->right;
	while ((p->right != NULL) && (p->data != x))
		p = p->right;
	if ((p->left == NULL)||(p->right==NULL))
	{
		cout << "未查询到数据!" << endl << endl;
		return;
	}
	cout << "找到数据!" << endl;
	p->data.print();
}

template<class temp>
void linklist<temp>::printlist()
{
	node<temp>* p = this->front->right;
	while (p->right != NULL)
	{
		p->data.print();
		p = p->right;
	}
	cout << endl;
}

int main()
{
	system("color 0A");
	cout << "双链表数据如下:" << endl;
	student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"liu"},{5,"zhao"} };
	linklist<student>list(stu, 5);
	list.printlist();

	cout << "下面检验插入操作:" << endl;
	cout << "插入学生的信息为:";
	student stu1(6, "fu");
	stu1.print();
	list.insert(3, stu1);
	cout << "双链表当前数据为:" << endl;
	list.printlist();

	cout << "下面检验删除操作:" << endl;
	cout << "以删除成员3为例:" << endl;
	cout << "执行函数……";
	list.del(3);
	cout << "双链表当前数据为:" << endl;
	list.printlist();

	cout << "下面检验查找操作:" << endl;
	cout << "查找同学的信息为:";
	stu1.print();
	list.search(stu1);

	cout << "下面检验替换操作:" << endl;
	cout << "替换进来的同学信息为:";
	student stu2(8, "zheng");
	stu2.print();
	list.change(2, stu2);
	cout << "双链表当前数据为:" << endl;
	list.printlist();
	return 0;
}

代码效果图:

北邮22信通:复习补充:双向链表的实现

运行结果:

北邮22信通:复习补充:双向链表的实现 

 

到了这里,关于北邮22信通:复习补充:双向链表的实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 北邮22级信通院数电:Verilog-FPGA(9)第九周实验(3)实现一个具有清零功能的按键计数器,对按键进行计数并显示

    北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客   目录 一.代码部分 1.1 counter.v 1.2 debounce.v 二.管脚分配 三.实现效果

    2024年02月05日
    浏览(41)
  • 北邮22级信通院数电:Verilog-FPGA(9)第九周实验(2)实现下降沿触发的JK触发器(带异步复位和置位功能)

    北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客   目录 ​编辑 一.代码部分 1.1 JK.v 1.2 JK_tb.v 二.仿真结果

    2024年02月05日
    浏览(31)
  • 双向链表的实现

      在本次的博客当中我们来向大家介绍一下双向循环链表,在介绍双向循环链表之前我们需要先来了解一下所有的链表的种类。   我们的链表大致分为八种:单向链表,双向链表,带头结点的链表,不带头结点的链表,循环链表,不循环的链表。经过组合一共分为八种。(单

    2024年02月01日
    浏览(24)
  • 【双向链表的实现】

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 1. 双向链表的结构 2. 双向链表的实现 2.1 头文件 ——双向链表的创建及功能函数的定义 2.2 源文件 ——双向链表的功能函数的实现 2.3 源文件 ——双向链表功能的测试 4.双向链表的操作示意图

    2024年02月05日
    浏览(30)
  • 双向链表的功能实现

          前言:我们已经学习并知道了单链表的实现,链表的实现方式不只是单链表一种,今天我们就来介绍一种新的结构,就是双链表结构,本质上是将节点间进行双向链接,从而使一些操作更加容易实现。 目录 1.双向链表的简介 2.双向链表的实现 带头节点的哨兵位的创建

    2024年02月05日
    浏览(36)
  • 数据结构——双向链表的实现

    注意: 双向链表又称带头双向循环链表 这⾥的“带头”跟前⾯我们说的“头节点”是两个概念,实际前⾯的在单链表阶段称呼不严 谨,但是为了同学们更好的理解就直接称为单链表的头节点。 带头链表⾥的头节点,实际为“ 哨兵位 ”,哨兵位节点不存储任何有效元素,只

    2024年02月06日
    浏览(31)
  • 【(数据结构)— 双向链表的实现】

    注意: 这里的 “带头” 跟前面我们说的 “头节点” 是两个概念,实际前面的在单链表阶段称呼不严 谨,但是为了同学们更好的理解就直接称为单链表的头节点。 带头链表里的头节点,实际为 “哨兵位” ,哨兵位节点不存储任何有效元素,只是站在这里“放哨 的” “哨

    2024年02月06日
    浏览(33)
  • 【数据结构】双向链表的实现

    我要扼住命运的咽喉,他却不能使我完全屈服。                      --贝多芬 目录 一.带头循环的双向链表的特点 二.不带头不循环单向链表和带头循环的双向链表的对比 三.初始化链表,创建哨兵结点 四.双向链表的各种功能的实现 1.双向链表的尾插 2.双向链表的打印 

    2023年04月10日
    浏览(26)
  • 北邮22级信通院数电:Verilog-FPGA(5)第四第五周实验 密码保险箱的设计

    北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.密码箱的功能和安全性 显示: 输入部分: 确认键: 复位键:

    2024年02月08日
    浏览(28)
  • 北邮22级信通院数电:Verilog-FPGA(11)第十一周实验(2)设计一个24秒倒计时器

    北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 1.1  counter_24.v 1.2  divide.v 1.3  debounce.v 二.管脚分配 三

    2024年02月04日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包