C语言—双链表

一、双向链表的结构

注意:这⾥的“带头”跟前⾯我们说的“头节点”是两个概念,实际前⾯在单链表阶段称呼不严谨,带头链表⾥的头节点,实际为“哨兵位”,哨兵位节点不存储任何有效元素,只是站在这⾥“放哨的”。
“哨兵位”存在的意义:遍历循环链表避免死循环。

二、双链表实现

注意:这里实现的双链表是指双向带头循环链表

(2.1)基本结构定义

为了双链表的复用性,这里将 int 重命名为LTDataType,后面如果要存储别的数据类型只需要将int更改就可以(自定义类型除外,自定义类型有些函数需要进行一定程度的修改),双链表节点中有一个数据域存储数据,两个指针域,其中 next 存储后继节点,prev 存储前驱节点,这里为了后面使用方便还将结构体类型重命名为LTNode。

(2.2)初始化链表

实现思路:该函数只需要一个参数,即指向头指针的二级指针,之所以用二级指针是因为我们实现的是带头双向循环链表,所以我们需要在该函数中申请一块不存储有效数据的空间,用来作为整个链表的头,并且让链表的头指针指向它,所以我们需要通过形参来实现改变链表头指针指向,所以需要传址调用,而这里的传址传的是头指针的地址,所以用二级指针。初始化时只有一个头节点,所以让它的 next 指针和 prev 指针都指向自己。

具体实现:

(2.3)打印数据

实现思路:因为打印链表数据,所以形参需要链表的头指针,因为头结点是不存储有效数据的,所以循环打印链表数据的时候可以从头节点的下一个节点开始循环,链表是循环的,当遍历回头节点的时候就说明所有有效节点都打印一遍了,而头节点又没有有效数据,所以当遍历到头节点的时候就退出循环。

具体实现:

(2.4)申请新节点

实现思路:先用动态内存申请函数申请出节点大小的空间,然后判断是否申请成功,申请失败报错,申请成功将数据插入,并将 next 指针和 prev 指针都指向自己,最后将申请成功的节点地址返回。(形参是要插入的数据)

具体实现:

(2.5)头部插入删除数据/尾部插入删除数据

(2.5.1)尾部插入

实现思路:该函数需要两个形参,一个用来找到链表的头指针,一个要插入的数据,在函数中调用前面写好的申请节点的函数申请新节点,然后就可以将节点插入链表尾部了,插入节点的写法可以有很多种,如果用下面的方法插入,前两句的顺序无所谓,但是后面两句顺序不可以改变,否则就会出问题。因为按照下图的写法,第三句(52行)中,phead的prev是原链表的尾节点,这句话的意思是让原链表的尾节点的next指针指向新节点,然后再让phead的prev指针指向新节点,这样新节点就成为了新的尾节点,如果交换顺序,先执行第四句,再执行第三句,phead的prev指针就指向新节点了,就不指向原来的尾节点了,那这句话中的next指针就是新节点的next指针而不是原链表尾节点的next指针。

具体实现:

(2.5.2)头部插入

实现思路:该函数需要两个参数,一个用来找到链表的头指针,一个要插入的数据,后面和尾插思路很像,先申请新节点,然后再插在原链表头后面就可以了,还是62,63两行顺序无所谓,64,65两行顺序不能改变。(注意:这是双向带头循环链表,头部插入是指插入在固定的头的后面,而不是插入一个新的头节点)

具体实现:

(2.5.3)尾部删除

实现思路:该函数只需要一个参数,即可以找到链表的头指针即可。因为链表是循环的,所以很容易就可以找到尾节点,就是头节点的前驱节点,我们可以先将要删除的节点用一个临时变量记录下来,先不要着急删除,先将删除节点会影响到的指针域进行重新赋值,然后再删,用临时变量记录要删除的节点避免了因为指针域的改变而找不到要删除的节点。

具体实现:

(2.5.4)头部删除

实现思路:该函数只需要一个形参,即可以找到链表的头指针,头删和尾删的思路很像,先定义一个临时变量记录要删除的节点,然后改变因删除节点受到影响的指针,最后释放节点,需要注意的是这里的头删指的是删除表头的后一个节点。

具体实现:

(2.6)查找

实现思路:该函数需要两个形参,一个用来找到链表的头指针,一个要查找的数据,因为双链表的头节点不存储有效数据,所以我们可以从头节点的下一个节点开始遍历,双链表是循环链表,所以当遍历回头节点的时候说明所有节点都已经遍历一次了,如果还没有找到,就需要退出循环,返回NULL。

具体实现:

(2.7)在pos位置之后插入数据

实现思路:这个函数可以配合查找使用,实现思路和头插,尾插很像,注意一下连接节点时的连接顺序即可。

具体实现:

(2.8)删除pos位置的数据

实现思路:先将pos的前后节点连接上,在释放pos即可。

具体实现:

(2.9)销毁链表

实现思路:我们可以从头节点的后一个节点开始循环删除,在释放当前节点前先将后继节点记录下来,防止释放后找不到,当除头节点外的所有节点都删除后再删除头节点,并将头指针置空。

具体实现:

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

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

相关文章

【C++】C++的引用

一.引用 1.引用的概念和定义 引用不是新定义⼀个变量,而是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同⼀块内存空间。 类型& 引用别名 引用对象; 2.引用的特征 a.引用在定义时必须初始化 …

Visual Studio--VS安装配置使用教程

Visual Studio Visual Studio 是一款功能强大的开发人员工具,可用于在一个位置完成整个开发周期。 它是一种全面的集成开发环境 (IDE)。对新手特别友好,使用方便,不需要复杂的去配置环境。用它学习很方便。 Studio安装教程 Visual Studio官…

详解前端开发都需要掌握的十个 JavaScript 基本数组函数

假设你正在开发一个复杂的 Web 项目。你的数据来自许多 API,你的工作是高效地处理、过滤和分析这些数据。你的时间很紧张,所以每一行代码都很重要。 这时学习高级 JavaScript 数组方法就会对你有所帮助。 这些函数不仅可以减少代码量,还可以…

阻塞socket 和非阻塞socket的区别(浅显易懂版)

什么是阻塞socket,什么是非阻塞socket。 对于这个问题,我们要先弄清什么是阻塞/非阻塞。 阻塞与非阻塞是对一个文件描述符指定的文件或设备的两种工作方式。 阻塞的意思是指,当试图对该文件描述符进行读写时,如果当时没有东西可…

基于Feign的远程调用

目录 前言 RestTemplate方式调用存在的问题 存在的问题 Feign Feign介绍 Feign的使用步骤 引入依赖 添加注解 编写Feign客户端 使用客户端(修改orderService) 原代码 修改后 总结 前言 RestTemplate方式调用存在的问题 以前利用RestTempla…

【Unity 100个实用小技巧】 UI分辨率适配

UI分辨率适配 学习实际项目中,分辨率适配的方案,基础版本。 以下适配以720*1680为基准适配 具体操作 Canvas Scaler的Screen Match Model 设置为Match Width Or Height,Match设置为0 这个设置,是以宽为基准进行分辨率适配 其实在…

uniapp__微信小程序使用秋云ucharts折线图双轴

1、子组件 <template><view class"charts-box"><qiun-data-charts type"line":opts"computedOpts":chartData"chartData"/></view> </template><script> export default {props: {chartData: {t…

【优选算法】(第三十五篇)

目录 验证栈序列&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 N叉树的层序遍历&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 验证栈序列&#xff08;medium&#xff09; 题目解析 1.题目链接&#xff1a;. - 力扣&#xff08;L…

只需5步,就可以使用大语言模型(LLM)打造高效的应用

01 概述 随着人工智能技术的飞速发展&#xff0c;大型语言模型&#xff08;LLM&#xff09;正逐渐成为各个领域的得力助手。从最初的文本理解、生成到翻译&#xff0c;这些模型在自然语言处理&#xff08;NLP&#xff09;中的出色表现&#xff0c;让它们在聊天机器人、虚拟助…

98. UE5 GAS RPG 实现技能眩晕效果

我们在技能伤害基类上面设置了对应的负面效果应用的配置项&#xff0c;用来实现技能的负面效果应用。 在之前实现火球术的负面效果时&#xff0c;我们我们在创建火球时&#xff0c;通过伤害基类上的创建技能配置用于后续应用。 在火球攻击到敌人时&#xff0c;通过函数库书写…

68 Netty

68 Netty 参考资料 【硬核】肝了一月的Netty知识点 概念 Netty 是一个高性能、异步事件驱动的网络应用框架&#xff0c;简化了 Java 网络编程&#xff0c;适用于构建高效、可扩展的网络服务器和客户端。 Netty 是基于 Java NIO 的异步事件驱动的网络应用框架&#xff0c;使…

Premiere半色调动漫风格视频叠加特效素材MOGRT

Premiere Pro 半色调叠加素材视频模板&#xff0c;使用这个半色调效果轻松设置视频或图像的样式。可以使用自定义选项&#xff0c;让工作流程更加高效。 特征&#xff1a; 15个半色调叠加效果。 Adobe Premiere Pro 2023 4K分辨率&#xff08;38402160&#xff09;。 包括视频…

回溯法与迭代法详解:如何从手机数字键盘生成字母组合

在这篇文章中&#xff0c;我们将详细介绍如何基于手机数字键盘的映射&#xff0c;给定一个仅包含数字 2-9 的字符串&#xff0c;输出它能够表示的所有字母组合。这是一个经典的回溯算法问题&#xff0c;适合初学者理解和掌握。 问题描述 给定一个数字字符串&#xff0c;比如 …

TikTok流量不好是为什么?是网络没选对吗?

很多人发现他们的TikTok视频观看量不高&#xff0c;点赞和分享率也低&#xff0c;就会开始怀疑是不是网络选择不当导致了这一问题。虽然网络确实是导致流量不佳的一大原因之一&#xff0c;但也不能忽视其他因素&#xff0c;包括内容质量、时机选择、互动参与等方面。本文将揭示…

桌面运维转网络要做什么准备,高级网工学习路线分享_运维转网络工程师好转岗吗

如果你的船不进来&#xff0c;请游过去。 做过桌面运维的朋友都知道&#xff0c;这个岗位相当于做牛做马。我做桌面运维的时候要修监控门禁&#xff0c;消防报警广播音响&#xff0c;还要懂暖通空调下水管道疏通&#xff0c;电梯保养与维护&#xff0c;我听到有些同行还得会修桌…

数据采集崩溃恢复:保障业务稳定运行的关键技术特性

一、场景描述 在当今信息时代&#xff0c;数据已成为企业核心竞争力的重要组成部分。对于许多企业而言&#xff0c;数据的采集、处理和分析至关重要。然而&#xff0c;在数据采集和处理过程中&#xff0c;系统崩溃或故障是无法避免的现象。如何在数据采集过程中确保数据的完整…

计量校准公司对校准工程师,会有什么资质要求?

计量校准是指利用一些计量校准工具&#xff0c;对机器、仪器等进行测量和校准。来实现基本功能的正常使用。计量校准安排&#xff0c;是指根据委托方的要求&#xff0c;按照计量器具校准标准&#xff0c;向社会提供计量器具校准服务的安排。今天&#xff0c;我们就来看看计量校…

腾讯音乐:从 Elasticsearch 到 Apache Doris 内容库升级,统一搜索分析引擎,成本直降 80%

导读&#xff1a; 为满足更严苛数据分析的需求&#xff0c;腾讯音乐借助 Apache Doris 替代了 Elasticsearch 集群&#xff0c;统一了内容库数据平台的内容搜索和分析引擎。并基于 Doris 倒排索引和全文检索的能力&#xff0c;支持了复杂的自定义标签计算&#xff0c;实现秒级查…

24最新新手入门指南:Stable Diffusion!

前言 Stable Diffusion&#xff0c;一款新兴的开源AI绘画软件&#xff0c;正逐渐成为数字艺术家和爱好者的新宠。它的强大功能让用户能够轻松创造出令人印象深刻的数字艺术作品。 无论你是专业艺术家还是艺术新手&#xff0c;Stable Diffusion都为你提供了一个探索创造力的新…

如何卸载电脑上的软件?电脑软件彻底删除的3个常见方法(强力卸载注册表)

电脑使用久了&#xff0c;难免会遇到卡顿&#xff0c;运行不流畅的情况&#xff0c;这属于正常现象。造成电脑卡顿的很大部分原因就是因为电脑安装了太多软件了&#xff0c;特别是一些“来路不明”的软件容易影响电脑运行速度。使用电脑时&#xff0c;定期清理电脑垃圾&#xf…