数据结构与算法中的双向链表
链表概念在现实世界中使用得很普遍。当我们使用 Spotify 播放队列中的下一首歌曲时,我们学到的单链表的概念就开始发挥作用。但是要播放队列中的上一首歌曲到底可以做什么呢?
在这篇博客中,我们将了解与数据结构相关的另一个概念,即双向链表。我们还将讨论使用 C 语言和实时应用程序的实现。
什么是双向链表?
链表是一种线性数据结构,包含以顺序方式连接的节点。该节点包含三个字段,即存储在该参考地址处的数据和指向该参考节点左侧和右侧的后继节点的两个指针。
左节点指针存储序列中前一个节点的内存地址,右节点存储下一个节点的内存地址。我们在这里使用动态内存分配而不是数组,以便可以在运行时根据执行的操作分配或取消分配内存大小。
在这个例子中,头指向第一个节点。引用节点的左指针存储NULL,最后一个节点的右指针也是如此。
为了对这个例子进行操作,我们可以进一步进行相应的更改。
双向链表的实现
1、在前面插入节点
为了完成上述操作,首先创建一个节点并使用动态内存分配内存。将头指向新节点,并在左节点和右节点中存储 NULL 值。
void front_add(){//allocate memory using dynamic memory allocation.newnode -> data = NULL;newnode -> prev = NULL;newnode -> next = head;head= newnode;
}
2.删除最前面的节点
要从前面删除节点,我们必须将引用地址的正确节点值存储在头部并释放第一个节点。
void front_del(){newnode=head;head= head->next ;head->prev = NULL;free(newnode);
}
3. 在末尾插入节点
要在末尾添加节点,我们必须遍历到末尾并将最后一个节点指向引用的新节点,反之亦然。
void end_add(){//allocate memory to newnodenewnode -> data= item; // temp=headwhile(temp ->next !=NULL){temp = temp->next;}temp->next= newnode;newnode -> prev = temp;newnode-> next = NULL;}
4.删除末尾节点
要删除末尾的节点,我们必须遍历链表并到达末尾。我们将使用指向最后一秒节点的指针。然后释放最后一个节点。
void rear_del(){while(temp -> next!=NULL){temp = temp->next; //temp=head}temp ->prev-> next = NULL;free(temp);
}
现在我们已经了解了基本操作,现在我们将逐步使用 C 实现双向链表。
#include<stdio.h>
#define MAX 5struct node{int data;struct node * prev;struct node * next;
};
struct node *head;
void front_add();
void front_del();
void rear_add();
void rear_del();
void display();int main(){int choice=0;while(choice!=6){printf("enter choice:\n");printf("\n1.front_add\n2.front_Del\n3.rear_add\n4.rear_del\n5.display\n6.exit");scanf("%d\n",&choice);switch(choice){case 1:front_add();break;case 2:front_del();break;case 3:rear_add();break;case 4:rear_del();break;case 5:display();break;case 6:printf("exiting...\n");break;default:printf("unknown choice\n");}}
}
void front_add(){struct node* newnode;int item;newnode = (struct node*)malloc(sizeof(struct node));printf("enter item value:\n");scanf("%d", &item);if(head == NULL){newnode -> next = NULL;newnode -> prev = NULL;newnode -> data = item;head = newnode;}else{newnode -> data = item;newnode -> prev = NULL;newnode -> next = head;head->prev = newnode;head= newnode;}
}
void front_del(){struct node *newnode;if(head->next == NULL){head = NULL;free(head);printf("\nnode deleted\n");}else{newnode=head;head= head->next ;head->prev = NULL;free(newnode);printf("deleted\n");}
}
void rear_add(){struct node *temp,*newnode;int item;newnode = (struct node*)malloc(sizeof(struct node));printf("enter item");scanf("%d", &item);newnode -> data= item;temp = head;while(temp ->next !=NULL){temp = temp->next;}temp->next= newnode;newnode -> prev = temp;newnode-> next = NULL;printf("inserted\n");}
void rear_del(){struct node *temp;temp=head;if(head->next==NULL){head = NULL;free(head);printf("deleted\n");}else{while(temp -> next!=NULL){temp = temp->next;}temp ->prev-> next = NULL;free(temp);printf("deleted\n");}
}
void display(){struct node *temp;temp = head;if(head==NULL){printf("empty\n");}else{while(temp!=NULL){printf("%d", temp->data);temp = temp->next;}}
}
此代码将为您提供所需的输出:
您有没有想过这些多人游戏是如何开发的,玩家可以在重复的循环中获得机会?这意味着最后一个玩家再次链接到第一个玩家以形成循环。
为了使这成为可能,我们引入了另一个与链表相关的概念。在这种情况下,循环链表很有用。
循环链表
在循环单链表中,链表的最后一个节点包含指向链表第一个节点的指针。双链表和单链表都可以使用这个概念。
该列表与其他两个列表的唯一区别是最后一个节点的右指针指向第一个节点,而头节点始终指向第一个节点本身。
结论
在我看来,链表的概念在解决复杂问题时非常重要和有用。在经历各种场景时,双向链表和循环单链表都是齐头并进的。我希望您喜欢阅读这个博客。请点赞并评论您对今天主题的看法。学习愉快!!
相关文章:

数据结构与算法中的双向链表
链表概念在现实世界中使用得很普遍。当我们使用 Spotify 播放队列中的下一首歌曲时,我们学到的单链表的概念就开始发挥作用。但是要播放队列中的上一首歌曲到底可以做什么呢? 在这篇博客中,我们将了解与数据结构相关的另一个概念,…...

数据安全治理的关键-数据分类分级工具
强大的资产发现能力 多种资产发现方式的组合应用,能够最大程度地提高资产发现能力。 灵活的敏感数据分类分级规则 内置丰富的敏感数据分类分级规则,支持正则表达式、关键词组、非结构化指纹、结构化指纹、机器聚类等多种匹配方式,并且规则…...

Spring集成Junit
目录 1、简介 2、Junit存在的问题 3、回顾Junit注解 4、集成步骤 4.1、导入坐标 4.2、Runwith 4.3、ContextConfiguration 4.4、Autowired 4.5、Test 4.6、代码 5、补充说明 5.1、Runwith 5.2、BlockJUnit4ClassRunner 5.3、没有配置Runwith ⭐作者介绍࿱…...

Java正则校验密码至少包含:字母数字特殊符号中的2种
一、语法 字符说明\将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如, n匹配字符 n。\n 匹配换行符。序列 \\\\ 匹配 \\ ,\\( 匹配 (。^匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n…...

Stable Diffusion教程(6) - 扩展安装
打开stable diffusion webUI界面 加载插件列表 依次点击扩展->可用->加载自 搜索插件 首先在搜索框输入你要安装的插件,然后点击插件后面的安装按钮 如果你需要的插件这里面没有找到,可通过通网址安装的方式安装。 在git仓库网址输入框输入的你插件…...

Jenkins通过OpenSSH发布WinServer2016
上一篇文章> Jenkins集成SonarQube代码质量检测 一、实验环境 jenkins环境 jenkins入门与安装 容器为docker 主机IP系统版本jenkins10.10.10.10rhel7.5 二、OpenSSH安装 1、下载 官网地址:https://learn.microsoft.com/zh-cn/windows-server/administration/op…...
字母异位词分组 LeetCode热题100
题目 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 思路 将字符串按字符升序排列后作为key,原字符串作为value存储到map上。 代码 class Solution…...
使用angular和electron 构建桌面应用
使用angular和electron 构建桌面应用 初始设置 新建一个angular app npm install -g @angular/cli ng new angular-electron cd angular-electron修改src/index.html文件内容 将绝对路径改为相对路径,加个点,使electron可以访问到angular文件资源 <base href=".…...

安达发制造工业迈向智能化:APS高级计划排程助力提升生产效率
随着市场竞争的加剧,制造企业纷纷寻求提高生产效率和降低成本的方法。近年来,越来越多的制造企业开始采用APS(高级计划与排程)系统,以优化生产计划和排程,提高生产效率,并在竞争中取得优势。 现代制造业通常面临复杂的…...

Flink - sink算子
水善利万物而不争,处众人之所恶,故几于道💦 文章目录 1. Kafka_Sink 2. Kafka_Sink - 自定义序列化器 3. Redis_Sink_String 4. Redis_Sink_list 5. Redis_Sink_set 6. Redis_Sink_hash 7. 有界流数据写入到ES 8. 无界流数据写入到ES 9. 自定…...

【项目 线程2】3.5 线程的分离 3.6线程取消 3.7线程属性
3.5 线程的分离 #include <stdio.h> #include <pthread.h> #include <string.h> #include <unistd.h>void * callback(void * arg) {printf("chid thread id : %ld\n", pthread_self());return NULL; }int main() {// 创建一个子线程pthread…...

Filebeat+ELK 部署
目录 //在 Node1 节点上操作 1.安装 Filebeat 2.设置 filebeat 的主配置文件 3.在 Logstash 组件所在节点上新建一个 Logstash 配置文件 4.浏览器访问 http://192.168.193.40:5601 登录 Kibana,单击“Create In…...

el-table点击表格某一行添加到URL参数,访问带参URL加载表格内容并滚动到选中行位置 [Vue3] [Element-plus 2.3]
写在最前 需求:有个表格列出了一些行数据,每个行数据点击后会加载出对应的详细数据,想要在点击了某一行后,能够将该点击反应到URL中,这样我复制这个URL发给其他人,他们打开时也能看到同样的行数据。 url会根…...

【树】 二叉树 堆与堆排序 平衡(AVL)树 红黑(RB)树
目录 1 树1.1 认识树1.2 树的相关概念1.3 树的表示孩子兄弟表示法 2 二叉树2.1 概念2. 2 特殊二叉树2.3 二叉树的性质2.4 二叉树的存储结构 3 堆 — 完全二叉树的顺序结构实现3.1 堆的概念3.2 核心代码3.3 堆应用1 堆排序2 TOP-K问题 4 二叉树的链式存储4.1 二叉链结构与初始化…...

信号平滑或移动平均滤波研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

黑客技术(网络安全)自学
一、黑客是什么 原是指热心于计算机技术,水平高超的电脑专家,尤其是程序设计人员。但后来,黑客一词已被用于泛指那些专门利用电脑网络搞破坏或者恶作剧的家伙。 二、学习黑客技术的原因 其实,网络信息空间安全已经成为海陆空之…...
使用七牛云、阿里云、腾讯云的对象存储上传文件
说明:存在部分步骤省略的情况,请根据具体文档进行操作 下载相关sdk composer require qiniu/php-sdkcomposer require aliyuncs/oss-sdk-php composer require alibabacloud/sts-20150401composer require qcloud/cos-sdk-v5 composer require qcloud_s…...

使用阿里云DataX完成数据同步
DataX DataX 是阿里云 DataWorks 数据集成的开源版本,在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、Hologres、DRDS, datab…...

《Kali渗透基础》13. 无线渗透(三)
kali渗透 1:无线通信过程1.1:Open 认证1.2:PSK 认证1.3:关联请求 2:加密2.1:Open 无加密网络2.2:WEP 加密系统2.3:WPA 安全系统2.3.1:WPA12.3.2:WPA2 3&#…...

python——案例六:判断字符串的长度
案例六:判断字符串的长度str"Study"print(len(str))#输出结果如下: #5...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...