【数据结构】第四讲:双向链表

目录

一、链表的分类

二、双向链表的结构及实现

1.带头双向链表的结构

2.创建节点

3.初始化

4.尾插

5.打印

6.头插

7.尾删

8.头删

9.在pos位置之后插入数据

10.删除pos节点

11.查找

12.销毁


个人主页:深情秋刀鱼@-CSDN博客

数据结构专栏:数据结构与算法

        循环链表这个轮回的思想很有意思。它强调了不管你今生是贫是富,如果持续行善积德,下辈子就会好过,反之就会遭到报应。

        就像每个人的人生一样,欲收获就得付出代价。双向链表既然是比单链表多了如可以反向遍历查找的数据结构,那么也就要付出一些小的代价。

一、链表的分类

        链表的结构复杂多样,总计有如下八种形式。

        虽然有这么多的链表的结构,但是我们实际中最常⽤还是两种结构: 单链表 双向带头循环链表。
1. ⽆头单向⾮循环链表:结构简单,⼀般不会单独⽤来存数据。实际中更多是作为其他数据结 构的⼦结构,如哈希桶、图的邻接表等等。另外这种结构在笔试⾯试中出现很多。
2. 带头双向循环链表:结构最复杂,⼀般⽤在单独存储数据。实际中使⽤的链表数据结构,都 是带头双向循环链表。另外这个结构虽然结构复杂,但是使⽤代码实现以        后会发现结构会带 来很多优势,实现反⽽简单了。

       

二、双向链表的结构及实现

1.带头双向链表的结构

         对于带头和不带头,在学习单链表是我们将其理解为链表的头节点(链表的第一个节点),这种称呼很不严谨,在本节中的带头和不带头指的是在该链表中书否含有哨兵结点,哨兵结点在双向链表中是名副其实的头节点,哨兵节点内不存储任何有效的数据,他的唯一作用是防止在遍历链表时进入死循环。

//双向链表的定义
typedef int LTDataType;//定义双向链表的节点
typedef struct ListNode
{LTDataType data;//数据域struct ListNode* next;//指向后继节点的指针struct ListNode* prev;//指向前驱节点的指针
}ListNode;

2.创建节点

ListNode* LTbuyNode(LTDataType x)
{ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));if (newNode == NULL){perror("malloc fail!");exit(1);}newNode->data = x;newNode->next = newNode;newNode->prev = newNode;//创建的新节点指向自身return newNode;
}

3.初始化

//初始化
void LTinit(ListNode** pphead)
{*pphead = LTbuyNode(-1);//哨兵位(不存储有效值)
}

4.尾插

//尾插
void LTpushBack(ListNode* phead, LTDataType x)
{assert(phead);ListNode* node = LTbuyNode(x);node->prev = phead->prev;node->next = phead;phead->prev->next = node;phead->prev = node;
}

5.打印

//打印
void LTprint(ListNode* phead)
{assert(phead);ListNode* pcur = phead->next;while (pcur != phead){printf("%d->", pcur->data);pcur = pcur->next;}printf("head\n");
}

6.头插

//头插
void LTpushFront(ListNode* phead, LTDataType x)
{assert(phead);ListNode* node = LTbuyNode(x);node->prev = phead;node->next = phead->next;phead->next->prev = node;phead->next = node;
}

7.尾删

//尾删
void LTpopBack(ListNode* phead)
{assert(phead && phead->next != phead);//链表不为空ListNode* pcur = phead->prev;phead->prev->prev->next = phead;phead->prev = phead->prev->prev;free(pcur);pcur = NULL;
}

8.头删

//头删
void LTpopFront(ListNode* phead)
{assert(phead && phead->next != phead);ListNode* pcur = phead->next;phead->next->next->prev = phead;phead->next = phead->next->next;free(pcur);pcur = NULL;
}

9.在pos位置之后插入数据

//pos位置之后插入数据
void LTinsert(ListNode* pos, LTDataType x)
{assert(pos);ListNode* node = LTbuyNode(x);pos->next->prev = node;node->prev = pos;node->next = pos->next;pos->next = node;
}

10.删除pos节点

//删除pos节点
void LTerase(ListNode* pos)
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

11.查找

//查找
ListNode* LTfind(ListNode* phead, LTDataType x)
{assert(phead && phead->next != phead);ListNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x){printf("找到了!\n");return pcur;}pcur = pcur->next;}printf("没有找到!\n");return NULL;
}

12.销毁

//销毁
void LTdestroy(ListNode* phead)
{assert(phead);ListNode* pcur = phead->next;while (pcur != phead){ListNode* next = pcur->next;free(pcur);pcur = next;}free(phead);phead = NULL;
}

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

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

相关文章

虚拟化技术 安装并配置ESXi服务器系统

安装并配置ESXi服务器系统 一、实验目的与要求 1.掌握创建VMware ESXi虚拟机 2.掌握安装VMware ESXi系统 3.掌握配置VMware ESXi系统的管理IP 4.掌握开启VMware ESXi的shell和ssh功能的方法 二、实验内容 1.安装VMware workstation 15或更高版本 2.创建VMware ESXi虚拟…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(三)

本系列课程,将重点讲解Phpsploit-Framework框架软件的基础使用! 本文章仅提供学习,切勿将其用于不法手段! 继续接上一篇文章内容,讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 当我们点击 submit 提…

基于t972 Android9 AP6256,如何在设置中添加5G热点选项,并使其正常打开

通过设置的的WiFi热点选项可以知道关键词“2.4GHz”,因此可以其全局搜索,在packages\apps\Settings\res\values\strings.xml文件下找到如下图所示, 从上面注释可以知道,选项按键选择2.4GHz触发的按键关键词是“wifi_ap_choose_2G…

✔ ★Java项目——设计一个消息队列(五)【虚拟主机设计】

虚拟主机设计 创建 VirtualHost实现构造⽅法和 getter创建交换机删除交换机创建队列删除队列创建绑定删除绑定发布消息 ★路由规则1) 实现 route ⽅法2) 实现 checkRoutingKeyValid3) 实现 checkBindingKeyValid4) 实现 routeTopic5) 匹配规则测试⽤例6) 测试 Router 订阅消息1…

分布式websocket IM即时通讯聊天开源项目如何启动

前言 自己之前分享了分布式websocket的视频有同学去fork项目了,自己启动一下更方便理解项目嘛。然后把项目启动需要的东西全部梳理出来。支持群聊单聊,表情包以及发送图片。 支持消息可靠,消息防重,消息有序。同时基础架构有分布式权限&…

深入教程:在STM32上实现能源管理系统

引言 能源管理系统(EMS)在提高能源效率、减少能源消耗和支持可持续发展方面起着关键作用。本教程将介绍如何在STM32微控制器上开发一个能源管理系统,这种系统能够监控和控制能源使用,适用于家庭自动化、工业控制系统以及任何需要…

jQuery Moblie 笔记14 开发跨平台移动设备网页

相关内容:jQuery Moblie基础、操作、移动设备仿真器、jQuery Moblie网页实例、jQuery Moblie的UI组件、…… jQuery推出了一套新的函数库jQuery Mobile,目的是希望能够统一当前移动设备的用户界面(UI)。 移动设备开发应用程序目前大致分为两种&#xff…

MLP手写数字识别(3)-使用tf.data.Dataset模块制作模型输入(tensorflow)

1、tensorflow版本查看 import tensorflow as tfprint(Tensorflow Version:{}.format(tf.__version__)) print(tf.config.list_physical_devices())2、MNIST数据集下载与预处理 (train_images,train_labels),(test_images,test_labels) tf.keras.datasets.mnist.load_data()…

强大而简洁:初学Python必须掌握的14个单行代码

Python的魅力与单行代码的重要性 Python,作为一种高级编程语言,自诞生以来就以其简洁、易读、易学的特性而广受开发者喜爱。其魅力不仅在于其强大的功能和广泛的应用领域,更在于其能够用简洁的代码实现复杂的功能,这种能力在很大…

Redisson 分布式锁和同步器

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 redisson 是基于redis的扩展库,使得redis除了应用于缓存以外,还能做队列…

FloodFill-----洪水灌溉算法(DFS例题详解)

目录 一.图像渲染: 代码详解: 二.岛屿数量: 代码详解: 三.岛屿的最大面积: 代码详解: 四.被围绕的区域: 代码详解: 五.太平洋大西洋水流问题: 代码详解&#x…

嵌入式单片机中必会的50个电路分享

单片机 电源 声音模块 收音机 485

操作系统-进程管理

1.进程的定义 2.进程的组成 3.进程的特点 4.进程控制结构 5.进程状态 6.进程挂起 6.线程优缺点 7.线程进程的比较 8 .为什么要使用线程 9.用户线程 9.内核线程 10.进程上下文切换信息储存在PCB中 11.fork()

JavaEE初阶Day 15:文件IO(1)

目录 Day 15:文件IO(1)IO文件1. 路径2. 文件的分类3. 使用Java针对文件系统进行操作3.1 属性3.2 构造方法3.3 方法 Day 15:文件IO(1) IO I:Input输入 O:Output输出 输入输出规则…

【python的魅力】:教你如何用几行代码实现文本语音识别

文章目录 引言一、运行效果二、文本转换为语音2.1 使用pyttsx32.2 使用SAPI实现文本转换语音2.3 使用 SpeechLib实现文本转换语音 三、语音转换为文本3.1 使用 PocketSphinx实现语音转换文本 引言 语音识别技术,也被称为自动语音识别,目标是以电脑自动将…

Tomcat启动闪退怎么解决(文末附终极解决方案)

AI是这么告诉我的 Tomcat启动时出现闪退问题可能由多种原因引起,以下是解决此类问题的一些通用方法: 检查环境变量: 确保已经正确设置了JAVA_HOME和JRE_HOME环境变量,并指向正确的Java安装路径。将Java的bin目录添加到系统的PATH…

c语言题目

一些关于c语言的题目 文章目录 一、计算程序输出二、以下程序运行时&#xff0c;若输入1abcedf2df<回车>输出结果是将flag的第二个bit置0结构体大小下列C程序执行后c输出结果为&#xff08;&#xff09;设有定义char *p[]{"Shanghai","Beijing",&quo…

scikit-learn:Python中的机器学习-1

简介&#xff1a;问题设置 什么是机器学习&#xff1f; 机器学习是关于构建具有可调参数的程序&#xff0c;这些参数可以自动调整&#xff0c;以便通过适应先前看到的数据来改善其行为。机器学习可以被认为是人工智能的一个子领域&#xff0c;因为这些算法可以被视为构建模块…

Python量化炒股的获取数据函数—get_index_stocks()

Python量化炒股的获取数据函数—get_index_stocks() 利用get_industry_stocks()函数可以获取在给定日期一个行业的所有股票代码列表&#xff0c;其语法格式如下&#xff1a; get_industry_stocks(industry_code, dateNone)各项参数的意义 参数date和返回值&#xff0c;都与g…

你知道什么是Charles吗?

什么是Charles? Charles中文名叫青花瓷&#xff0c;它是一款基于HTTP协议的代理服务器&#xff0c;通过成为电脑或者浏览器的代理&#xff0c;然后截取请求和请求结果达到分析抓包的目的。它跨平台、半免费&#xff0c;与免费版本不同的是&#xff0c;半免费版本的Charles重启…