[数据结构] -- 双向循环链表

 🌈 个人主页:白子寰
🔥 分类专栏:C++打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~
💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~)

 

目录

双向循环链表

结构

介绍

图示

双向链表的实现

在List.h中

定义双向链表的结构

实现双向链表的接口/方法

 在List.c中

初始化

销毁链表

打印链表

判断链表是否为空

尾插

测试

头插

测试

​编辑尾删

测试

​编辑头删

测试

​编辑在pos位置之后插入数据

测试

​编辑删除pos指定节点

测试

查找链表的指定元素


双向循环链表

结构

包含数据域,指针域(前驱节点prev和后继节点next)


介绍

结构最复杂,一般用在单独存储数据。

实际中使用的链表数据结构,都是带头双向循环链表。

另外这个结构虽然结构复杂,

但是使用代码实现以后会发现结构会带来很多优势,但实现简单


图示



双向链表的实现

在List.h中

定义双向链表的结构

typedef int LTDataType;
typedef struct ListNode
{
	LTDataType data;
	struct ListNode* prev;
	struct ListNode* next;
}LTNode;

 

实现双向链表的接口/方法

//初始化
LTNode* LTInit();
//销毁链表
void LTDestroy(LTNode* phead);
//打印链表
void LTPrint(LTNode* phead);
//判断链表是否为空
bool LTEmpty(LTNode* phead);
//尾插
void LTPushBack(LTNode* phead, LTDataType x);
//头插
void LTPushFront(LTNode* phead, LTDataType x);
//尾删
void LTPopBack(LTNode* phead);
//头删
void LTPopFront(LTNode* phead);
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x);
//删除pos指定节点
void LTErase(LTNode* pos);
//查找链表的指定元素
LTNode* LTFind(LTNode* phead, LTDataType x);


 

 在List.c中

初始化

//初始化
LTNode* LTInit()
{
	LTNode* phead = LTBuyNode(-1);
	return phead;
}


销毁链表

//销毁
void LTDestroy(LTNode* phead)
{
	assert(phead);

	LTNode* pcur = phead->next;
	while (pcur != phead)
	{
		LTNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}

	//最后释放头节点的内存并置空
	free(phead);
	phead = NULL;
}


打印链表

//打印双向链表
void LTPrint(LTNode* phead)
{
	assert(phead);

	LTNode* pcur = phead->next;
	while (pcur != phead)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("\n");
}


判断链表是否为空

bool LTEmpty(LTNode* phead)
{
	if (phead->next == phead)
	{
		return true;
	}

	else { return false; }
}


尾插

//尾插
void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);

	LTNode* newnode = LTBuyNode(x);

	newnode->next = phead;
	newnode->prev = phead->prev;

	phead->prev->next = newnode;
	phead->prev = newnode;
}

后四行的方向和赋值问题 

有新开节点newnode

 

测试



头插

//头插
void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);

	LTNode* newnode = LTBuyNode(x);
	LTNode* pcur = phead->next;

	newnode->next = pcur;
	newnode->prev = phead;

	phead->next = newnode;
	pcur->prev = newnode;
}
测试



尾删

//尾删
void LTPopBack(LTNode* phead)
{
	assert(phead);

	LTNode* p1 = phead->prev;
	LTNode* pcur = p1->prev;

	pcur->next = phead;
	phead->prev = pcur;

	free(p1);
	p1 = NULL;
}
测试



头删

//头删
void LTPopFront(LTNode* phead)
{
	assert(phead);

	LTNode* pcur = phead->next->next;
	LTNode* p1 = phead->next;

	phead->next = pcur;
	pcur->prev = phead;

	free(p1);
	p1 = NULL;
}
测试



在pos位置之后插入数据

//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);

	 LTNode* newnode = LTBuyNode(x);

	 newnode->next = pos->next;
	 newnode->prev = pos;

	 //如果pos是最后一个节点
	 if (pos->next == NULL)
	 {
		 newnode->next = NULL;
	 }
	 else
	 {
		 pos->next->prev = newnode;
	 }

	 pos->next = newnode;
}
测试



删除pos指定节点

//删除pos节点
void LTErase(LTNode* pos)
{
	assert(pos);

	LTNode* p1 = pos->prev;
	LTNode* pcur = pos->next;

	p1->next = pcur;
	pcur->prev = p1;

	free(pos);
	pos = NULL;
}
测试



查找链表的指定元素

//查找元素
LTNode* LTFind(LTNode* phead, LTDataType x)
{
	assert(phead);

	LTNode* pcur = phead->next;
	while (pcur != phead)    //注意循环条件!
	{
		if (pcur->data == x)
		{
			return pcur;
		}

		else
		{
			pcur = pcur->next;
		}
	}
	return NULL;
}


 

 

 ***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。

等等等等一下,分享最近喜欢的一句话:

“人生如逆旅,我亦是行人”。

我是白子寰,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!! 
好了划走吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/644358.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java实现图书系统

首先实现一个图书管理系统,我们要知道有哪些元素? 1.用户分成为管理员和普通用户 2.书:书架 书 3.操作的是: 书架 目录 第一步:建包 第二步:搭建框架 首先:完成book中的方法 其次:完成BookList 然后:完成管理员界面和普通用户界面 最后:Main 第三步:细分方法 1.退…

十二、shell编程之awk

12.1 什么是awk 虽然sed编辑器是非常方便自动修改文本文件的工具,但其也有自身的限制。通常你需要一个用来处理文件中的数据的更高级工具,它能提供一个类编程环境来修改和重新组织文件中的数据。这正是awk能够做到的。 awk程序是Unix中的原始awk程序的…

JVM(三)

在上一篇中,介绍了JVM组件中的类加载器,以及相关的双亲委派机制。这一篇主要介绍运行时的数据区域 JVM架构图: JDK1.8后的内存结构: (图片来源:https://github.com/Seazean/JavaNote) 而在运行时数据区域中&#…

Redis第18讲——Redis和Redission实现延迟消息

即使不是做电商业务的同学,也一定知道订单超时关闭这种业务场景,这个场景大致就是用户下单后,如果在一定时间内未支付(比如15分钟、半小时),那么系统就会把这笔订单给关闭掉。这个功能实现的方式有很多种&a…

Windows远程连接命令?

Windows操作系统提供了多种远程连接命令,使用户可以通过网络连接到远程计算机,并在远程操作系统上执行操作。远程连接命令可方便实现远程工作、故障排查和系统维护等任务。本文将介绍几种常见的Windows远程连接命令及其基本使用方法。 远程连接命令 Win…

面向对象编程的奥秘:封装与继承

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、封装的魅力 封装的应用 封装示例 二、继承的力量 继承的应用 继承示例 三、总结 一…

OpenWrt U盘安装使用 详细教程 x86/64平台 软路由实测 系列一

1 官方稳定 版:OpenWrt 23.05 OpenWrt Downloads #根据实际情况选择 PC支持uefi,选择版本:https://downloads.openwrt.org/releases/23.05.3/targets/x86/64/openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img.gz 2 rufus 制作U盘启动 3 制作好的U盘,接入主…

Maven多环境打包配置

一、启动时指定环境配置文件 在启动springboot应用的jar包时,我们可以指定配置文件,通常把配置文件上传到linux服务器对应jar包的同级目录,或者统一的配置文件存放目录 java -jar your-app.jar --spring.config.location/opt/softs/applicat…

新能源汽车的电驱热管理

前言 新能源汽车的电驱热管理是指维持电动汽车电池、电机和电控系统在适宜的工作温度范围内,保障车辆高效、安全、稳定运行的技术方案。随着新能源汽车的快速发展和普及,电驱热管理技术也日益成为关注焦点。本文将从电池、电机和电控系统三个方面介绍新…

Linux--线程的认识(一)

线程的概念 线程(Thread)是操作系统中进行程序执行的最小单位,也是程序调度和分派的基本单位。它通常被包含在进程之中,是进程中的实际运作单位。一个线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线…

【leetcode面试经典150题】-80. 删除有序数组中的重复项 II

【leetcode面试经典150题】-80. 删除有序数组中的重复项 II 1 题目介绍2 个人解题思路2.1 代码2.2 思路 3 官方题解 1 题目介绍 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组…

【DZ模板】克米设计APP手机版本地化+完美使用

模版介绍 【DZ模板】价值288克米设计APP手机版DZ模板 数据本地化完美使用 腾讯官方出品discuz论坛DIY的后台设置,功能齐全,论坛功能不亚于葫芦侠,自定义马甲,自定义认证,自定义广告,完全可以打造出自己想…

Redis教程(十五):Redis的哨兵模式搭建

一、搭建Redis一主二从 分别复制三份Redis工作文件夹,里面内容一致 接着修改7002的配置文件,【redis.windows-service.conf】 port 7002 改成 port 7002 slaveof 127.0.0.1 7001 7003也同样修改 port 7003 slaveof 127.0.0.1 7001 这样就指定了700…

从0开始带你成为Kafka消息中间件高手---第三讲

从0开始带你成为Kafka消息中间件高手—第三讲 实际上来说,每次leader接收到一条消息,都会更新自己的LEO,也就是log end offset,把最后一位offset 1,这个大家都能理解吧?接着各个follower会从leader请求同…

读人工智能时代与人类未来笔记14_管控人工智能

1. 管控人工智能 1.1. 历史上的战场进一步推进到与数字网络相连的所有地方 1.2. 数字程序现在控制着一个由众多实体系统构成的庞大且仍在不断增长的领域,而且越来越多的此类系统已实现网络化 1.2.1. 在某些情况下甚至连门锁和冰箱都实现了网络化 1.2.2. 这催生出…

vue3中element-plus下拉菜单与图标的使用

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: h…

十、通配符和正则表达式

10.1 通配符 通配符是由shell处理的, 它只会出现在 命令的“参数”里。当shell在“参数”中遇到了通配符 时,shell会将其当作路径或文件名去在磁盘上搜寻可能的匹配:若符合要求的匹配存在,则进 行代换(路径扩展);否则就将该通配…

21.Happens-Before原则

文章目录 Happens-Before原则1.Happens-Before规则介绍2.规格介绍2.1.顺序性规则(as-if-serial)2.2.volatile规则2.3.传递性规则2.4.监视锁规则2.5.start规则2.6.join()规则 Happens-Before原则 JVM内存屏障指令对Java开发工程师是透明的,是JMM对JVM实现的一种规范和…

HE TB PPDU MU-RTS

看起来像是MU-RTS的触发帧的应答不是HE TB PPDU,而是传统得的帧,应答CTS。 非AP 的STA,是不能发送触发帧,也就是说,触发帧,只能是由AP发送给STA

RedHat9 | DNS剖析-配置主DNS服务器实例

一、实验环境 1、BIND软件包介绍 BIND软件是一款开放源码的DNS服务器软件,由美国加州大学Berkeley分校开发和维护,全称为Berkeley Internet Name Domain。该软件在DNS(域名系统)领域具有重要地位,是目前世界上使用最…