C语言双向链表

news2025/1/21 4:57:50

文章目录

  • 前言
  • 双向链表
    • 链表头结点的创建
    • 节点尾插与尾删
    • 节点头插与头删
    • 特定位置插入或删除节点
    • 链表节点查找
    • 双向链表的销毁
  • 链表的打印

前言

假期时间因为为学校开学考试做准备所以一直没更新博客,今天开始博客会陆续更新。

双向链表

之前我们说过了顺序表和单链表,这次介绍双向链表,双向链表在使用上要比单链表简单,结构比单链表复杂一些,需要两个指针域,其结构如下图,其中头结点数据域不动(不要存放指针长度一类因为有时候我们不确定链表节点数据类型,如果是char类型而节点数大于128,那么就会出现bug),带有头结点可方便对其操作。
在这里插入图片描述

双向链表节点代码如下:

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

与单链表相同无非是双向链表的增删改查。

链表头结点的创建

ListNode* ListCreate()
{
	ListNode* head = (ListNode*)malloc(sizeof(ListNode));
	head->next = head;
	head->prev = head;
	return head;
}

这里别忘了是双向链表,要给两个指针都赋值,因为是头结点(PS:头结点数据域一般是垃圾值)所以就指向自己。

节点尾插与尾删

// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x)
{
	ListNode* tail = pHead->prev;
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	newnode->data = x;
	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = pHead;
	pHead->prev = newnode;
}

这里就体现出双向链表的优势,我们不用遍历就可以直接找到链表的尾结点。

// 双向链表尾删
void ListPopBack(ListNode* pHead)
{
	ListNode* tail = pHead->prev;
	ListNode* TailPrev = tail->prev;
	free(tail);
	TailPrev->next = pHead;
	pHead->prev = TailPrev;
}

尾插时不要忘了让节点指向头结点。

节点头插与头删

// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	newnode->data = x;
	newnode->next = pHead->next;
	pHead->next->prev = newnode;
	pHead->next = newnode;
	newnode->prev = pHead;
}

这里注意哈,链表的头插与头删是在头结点之后位置进行,这里例出一幅头插图作为参考(艺术细胞为0后续可能解锁画图软件,这里先凑合看)。
在这里插入图片描述

// 双向链表头删
void ListPopFront(ListNode* pHead)
{
	ListNode* cur = (ListNode*)malloc(sizeof(ListNode));
	cur = pHead->next;
	pHead->next = cur->next;
	cur->next->prev = pHead;
	free(cur);
}

头插和头删要注意顺序,否则可能找不到头结点的下一个节点。在这里插入图片描述

特定位置插入或删除节点

// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	newnode->data = x;
	newnode->next = pos;
	newnode->prev = pos->prev;
	pos->prev->next = newnode;
	pos->prev = newnode;
}
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;
	free(pos);
}

这里还是注意一下代码顺序无其他重点。

链表节点查找

// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return pHead;
}

若最后没有找到该数值则返回头结点。

双向链表的销毁

// 双向链表销毁
void ListDestory(ListNode* pHead)
{
	ListNode* newhead = pHead->next;
	ListNode* cur = newhead->next;
	while (cur->next!=pHead)
	{
		free(newhead);
		newhead = cur;
		cur = newhead->next;
	}
	free(pHead);
	pHead == NULL;
}

这里别忘了最后删除并置空头结点,置空头结点的原因是使用者在主函数还有头结点的地址,但此时头结点已被释放(野指针),若再次调用头结点则可能出现bug。

链表的打印

// 双向链表打印
void ListPrint(ListNode* pHead)
{
	ListNode* newnode = pHead->next;
	while (newnode!=pHead)
	{
		printf("%d ", newnode->next->data);
		newnode = newnode->next;
	}
}

比较简单,不做赘述。
双向链表许多函数的while循环是判断其节点是否与头结点相等,而不是其节点是否为空,这里要注意与单链表区分,最后代码其实还应该加上断言(assert)函数判断是否为空,但博主这里没有加(是故意的还是不小心的)。
在这里插入图片描述
这里纯粹是懒得加了,这个习惯不是很好,大家不要学我,最好还是自己加一下。
最后期待你的三连,若有错误欢迎私信或评论区指出。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

加密狗软件有什么作用?

加密狗软件是一种用于加密和保护计算机软件和数据的安全设备。它通常是一个硬件设备,可以通过USB接口连接到计算机上。加密狗软件的作用主要体现在以下几个方面: 软件保护:加密狗软件可以对软件进行加密和授权,防止未经授权的用户…

K8S:kubectl陈述式、声明式资源管理及金丝雀部署

文章目录 一.陈述式资源管理方法1.陈述式资源管理概念2.基本信息查看(1)查看版本信息(2)查看资源对象简写(3)查看集群信息(4)配置kubectl自动补全(5)node节点…

【Java实战项目】【超详细过程】—大饼的图片服务器4

目录 1.引入servlet依赖2.处理客户端请求2.1 上传图片2.1.1.获取图片属性写入数据库(1)创建factory对象和fileUpload对象为获取图片信息做准备(2)将获取到的文件信息存到列表items中(3)获取列表items中第一…

无涯教程-JavaScript - XNPV函数

描述 XNPV函数返回的现金Stream量表的净现值不一定是周期性的。要计算一系列定期现金Stream量的净现值,请使用NPV函数。 语法 XNPV (rate, values, dates)争论 Argument描述Required/OptionalRateThe discount rate to apply to the cash flows.RequiredValues 与日期付款时…

(已解决)AttributeError: module ‘cv2.gapi.wip.draw‘ has no attribute ‘Text‘

问题描述 今天再跑Caption-Anything项目的时候,最开始的时候就报了这样一个错误:AttributeError: module cv2.gapi.wip.draw has no attribute Text。 Caption-Anything是一种多功能的图像处理工具,结合了Segment Anything,Visual…

前端项目开发流程

一 参加需求对称(评审)会议 时间:在产品设计完成以后,进入正式的开发流程之前 组织者:产品&项目经理 目的:统一大家对产品的认识,及时发现产品设计缺陷,尽可能降低后续修改需求的频率 参与者&#xff…

短信验证码的登录注册功能

1 基于session实现登录流程 1.1发送验证码: 用户在提交手机号后,会校验手机号是否合法,如果不合法,则要求用户重新输入手机 如果手机号合法,后台此时生成对应的验证码,同时将验证码进行保存,然…

【计算机视觉 | 目标检测】干货:目标检测常见算法介绍合集(二)

文章目录 十六、EfficientDet十七、Deformable DETR十八、YOLOX十九、Sparse R-CNN二十、Contour Proposal Network二十一、VarifocalNet二十二、Libra R-CNN二十三、Stand-Alone Self Attention二十四、ThunderNet二十五、Hierarchical Transferability Calibration Network二…

垃圾收集算法

1.如何判断对象是否存活? 1.1引用计数算法 基本思路: 在对象中添加一个引用计数器每当有一个地方引用它的时候,计数器就加1每当有一个引用失效的时候,计数器就减-1当计数器的值为0的时候,那么该对象就是可被GC回收的…

leetcode 2366. Minimum Replacements to Sort the Array(数组排序的最少替换数)

数组nums中的元素nums[ i ] 可以替换为任意两个数a, b, 前提是ab nums[ i ]. 把数组nums变为升序&#xff08;可以有相等&#xff09;数组需要多少次替换。 思路&#xff1a; 排序数组是左边的元素<右边元素&#xff0c;以右边元素为边界。 所以从右到左遍历数组&#xf…

第二章 网络应用

第一节 计算机网络应用体系结构 三种类型&#xff1a; 1. 客户/服务器&#xff08;c/s&#xff09;结构 最主要的特征是通信只在客户与服务器之间进行&#xff0c;客户与客户之间不进行直接通信。 2. P2P(Peer to Peer) 结构 每个对等端都同时具备C/S应用的客户与服务器的…

Python算法练习 9.12

leetcode 643 子数组最大平均数 给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。 请你找出平均数最大且 长度为 k 的连续子数组&#xff0c;并输出该最大平均数。 任何误差小于 10-5 的答案都将被视为正确答案 输入&#xff1a;nums [1,12,-5,-6,50,3], k 4 输出…

buuctf web [极客大挑战 2019]Secret File

纯网页&#xff0c;看一下源码。 这一块源码中有个隐藏的超链接&#xff0c;点击后跳转到了新页面。 新页面的源码里&#xff0c;也有一处可以跳转的超链接。 点进新页面啥也没有了。 单看网页&#xff0c;什么也没有&#xff0c;尝试用burp抓包试试。 在/Archive_room.php跳…

循环语句详解

文章目录 循环语句详解1. 循环使用 v-for 指令2. v-for 还支持一个可选的第二个参数&#xff0c;参数值为当前项的索引3. 模板template 中使用 v-for4. v-for 迭代对象-第一个参数为value5. v-for的第二个参数为键名6. v-for的第三个参数为索引7. v-for迭代整数8. computed计算…

运营商大数据精准营销获客?

多年来&#xff0c;大数据运营商一直致力于为企业提供互联网大数据精准营销的新项目&#xff0c;并以确保自身信息安全为前提。例如&#xff0c;如果移动用户查看了任何网站&#xff0c;在网页上搜索了任何关键词&#xff0c;登录了应用程序&#xff0c;给任何人打了电话&#…

【Linux】多线程互斥与同步

文章目录 一、线程互斥1. 线程互斥的引出2. 互斥量3. 互斥锁的实现原理 二、可重入和线程安全三、线程和互斥锁的封装1. 线程封装1. 互斥锁封装 四、死锁1. 死锁的概念2. 死锁的四个必要条件3. 避免死锁 五、线程同步1. 线程同步的理解2. 条件变量 一、线程互斥 1. 线程互斥的…

kaggle近三年NLP比赛top方案汇总及新赛推荐

NLP的赛题任务主要有文本分类、情感分析、关系抽取、文本匹配、阅读理解、问答系统等&#xff0c;自Google开发的NLP处理模型BERT被广泛应用后&#xff0c;目前解决NLP任务的首选方案就是深度学习方法&#xff08;textCNN、LSTM、GRU、BiLSTM、Attention等&#xff09;&#xf…

CSS 纵横比属性:aspect-ratio

CSS 属性 aspect-ratio 为盒子规定了纵横比&#xff08;宽高比&#xff09;&#xff0c;这个纵横比可以用于计算 auto 尺寸以及其他布局函数。

《算法竞赛·快冲300题》每日一题:“点灯游戏”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 点…

如何通过局域网共享文件

需求环境&#xff1a;公司有多个部门&#xff0c;不同用户与部门使用不同文件 业务背景&#xff1a;一台windows服务器,若干客户端 需要技能&#xff1a; 熟悉windows系统管理&#xff0c; 包含计算机管理、 硬盘硬件、 用户管理、 share and storage management 项目方案…