C语言.数据结构.双向链表

数据结构.双向链表

  • 1.双向链表的结构
    • 1.1链表的简单介绍
    • 1.2图文分析
  • 2.实现双向链表
    • 2.1链表的初始化
      • 2.1.1初始化
      • 2.1.2节点的申请
    • 2.2链表的打印
      • 2.2.1代码实现
      • 2.2.2图文分析
    • 2.3链表的尾插
      • 2.3.1代码实现
      • 2.3.2图文分析
    • 2.4链表的头插
      • 2.4.1代码实现
      • 2.4.2图文分析
    • 2.5链表的尾删
      • 2.5.1代码实现
      • 2.5.2图文分析
    • 2.6链表的头删
      • 2.6.1代码实现
      • 2.6.2图文分析
    • 2.7在pos位置之后插入数据
      • 2.7.1代码实现
      • 2.7.2图文分析
    • 2.8删除pos位置节点
      • 2.8.1代码实现
      • 2.8.2图文分析
    • 2.9查找节点
      • 2.9.1代码实现
    • 2.10链表的销毁
      • 2.10.1代码实现
      • 2.10.2图文分析
  • 3.顺序表和双向链表的分析

1.双向链表的结构

1.1链表的简单介绍

在这里插入图片描述

  • 注意:这里的“带头”跟前面所说的“头节点”是两个概念,实际前面的在单链表阶段称呼不严谨,但是为了方便理解,就直接称为单链表的头节点
  • 带头链表里的头节点,实际为“哨兵位”,哨兵位节点不存储任何的有效元素,只能站在这里“放哨的”
  • “哨兵位”存在的意义
    遍历循环链表避免死循环。

1.2图文分析

在这里插入图片描述

2.实现双向链表

2.1链表的初始化

2.1.1初始化

//链表的初始化
void LTInit(LTNode** pphead)
{//哨兵位节点不存储任何的有效元素,只能站在这里“放哨的”,传递一个什么样的值都可以*pphead = LTBuyNode(-1);
}

2.1.2节点的申请

LTNode* LTBuyNode(LTDataType x)
{LTNode* node = (LTNode*)malloc(sizeof(LTNode));if (node == NULL){perror("malloc fail!");exit(1);}//走到这 证明申请成功node->data = x;//给双向链表一个哨兵位,使得自己指向自己node->next = node->prev = node;
}

2.2链表的打印

2.2.1代码实现

//链表的打印
void LTPrint(LTNode* phead)
{//哨兵位不用打印,有效节点为哨兵位的下一个节点LTNode* pcur = phead->next;//本质还是遍历链表while (pcur != phead){printf("%d->", pcur->data);//pcur指针往下走pcur = pcur->next;}printf("\n");
}

2.2.2图文分析

在这里插入图片描述

2.3链表的尾插

2.3.1代码实现

//链表的尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);//让newnode插在phead->prev(头结点的前一个节点)和phead之间newnode->prev = phead->prev;newnode->next = phead;phead->prev->next = newnode;phead->prev = newnode;//两者不能交换位置
}

2.3.2图文分析

在这里插入图片描述

2.4链表的头插

2.4.1代码实现

//链表的头插
void LTPushFront(LTNode* phead, LTDataType x)
{//头插:插在有效节点的前面,也就是头节点的后面assert(phead);LTNode* newnode = LTBuyNode(x);//把newnode节点插在phead和phead->next之间newnode->prev = phead;newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;//这两行代码不能完全交换
}

2.4.2图文分析

在这里插入图片描述

2.5链表的尾删

2.5.1代码实现

//链表的尾删
void LTPopBack(LTNode* phead)
{//链表必须有效,且链表不能为空(只有一个哨兵位,自己指向自己)assert(phead && phead->next != phead);//要删除的节点LTNode* del = phead->prev;//要改变尾节点的前一个节点的指向 应该指向的是头节点(原本指向del的)del->prev->next = phead;//头结点的前一个节点就应该指向del->prevphead->prev = del->prev;//把尾节点内存释放掉,删除del节点free(del);del = NULL;
}

2.5.2图文分析

在这里插入图片描述

2.6链表的头删

2.6.1代码实现

//链表的头删
void LTPopFront(LTNode* phead)
{//链表必须有效,且链表不能为空(只有一个哨兵位,自己指向自己)assert(phead && phead->next != phead);//要删除的节点 -> 链表中第一个有效节点LTNode* del = phead->next;del->next->prev = phead;phead->next = del->next;//这两个可以交换//删除del节点free(del);del = NULL;
}

2.6.2图文分析

在这里插入图片描述

2.7在pos位置之后插入数据

2.7.1代码实现

//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);//也就是说,在pos与pos->next之间插入一个x节点newnode->next = pos->next;newnode->prev = pos;//既然是双向链表,肯定是有两个方向pos->next->prev = newnode;pos->next = newnode;
}

2.7.2图文分析

在这里插入图片描述

2.8删除pos位置节点

2.8.1代码实现

//删除pos位置节点
void LTErase(LTNode* pos)
{assert(pos);//就是把pos->prev和pos->next之间删除pos节点pos->next->prev = pos->prev;pos->prev->next = pos->next;//删除pos位置节点free(pos);pos = NULL;
}

2.8.2图文分析

在这里插入图片描述

2.9查找节点

2.9.1代码实现

//查找节点
LTNode* LTFind(LTNode* phead, LTDataType x)
{//就是自己传递的形参x 与链表中的有效数据进行对比,遍历链表LTNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x){return pcur;}pcur = pcur->next;}//走到这,证明没有找到对应的数据,返回一个空指针return NULL;
}

2.10链表的销毁

2.10.1代码实现

//链表的销毁
void LTDestroy(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){//先把要删除的下一个节点的位置保存下来,否则就找不到下一个节点的位置LTNode* next = pcur->next;free(pcur);pcur = next;}//此时pcur指向了phead,而phead并未销毁,free(phead);phead = NULL;
}

2.10.2图文分析

在这里插入图片描述

3.顺序表和双向链表的分析

不同点顺序表链表(单链表)
存储空间上物理上一定是连续的逻辑上连续,但是物理上不一定连续
随机访问支持O(l)不支持O(N)
任意位置插入或删除元素可能需要搬移元素,效率低O(N)只需要修改指针指向
插入动态顺序表,空间不够时需要扩容没有容量的概念
应用场景元素效率存储+频繁访问任意位置插入或删除频繁

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

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

相关文章

CMMI软件能力成熟度评估标准

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl CMMI概述 CMMI,全称为Capability Maturity Model Integration,即能力成熟度模型集成,是在原有的CMM(Capability Maturity Mo…

一文吃透!如何在鸿蒙上开发Unity游戏的方法!

实际效果: 使用 Webview 在鸿蒙设备上运行 Unity 游戏需要几个步骤? 用 Webview 在鸿蒙上运行 Unity 游戏 ①创建鸿蒙全屏工程 在 DevEco 中创建一个新工程,模板选择 Full Screen Ability。 ②添加 Webview 这个工程的布局很简单&#xf…

esp32-c6所有配套教程

1.介绍 本文是esp32-c6所有资料的介绍 如果需要详细代码的话请访问下面这个链接 esp32-c6使用教程wifi(espidf修改成arduino)附带代码websocket,舵机,点灯【2024年】-CSDN博客 配置环境 视频教程 0-2设置开发环境_哔哩哔哩_bi…

策略模式+简单工厂

🍇工厂模式 🍈工厂模式向策略模式过度——工厂加一个保安 🍏策略模式 🍐策略模式简单工厂 声明本文需要理解多态的基础上才能来学习 欢迎前来学习——继承和多态 学习记录 工厂模式 需要什么就生成什么 // 工厂模式 class Fact…

Flink任务如何跑起来之 1.DataStream和Transformation

Flink任务如何跑起来之 1.DataStream和Transformation 1. 滥觞 在使用Flink完成业务功能之余,有必要了解下我们的任务是如何跑起来的。知其然,知其所以然。 既然重点是学习应用程序如何跑起来,那么应用程序的内容不重要,越简单…

好家风短视频:成都鼎茂宏升文化传媒公司

好家风短视频:传承与发扬家庭美德的新载体 在数字时代的浪潮中,短视频以其简短、生动、直观的特点,成为了人们获取信息、传递情感的重要渠道。成都鼎茂宏升文化传媒公司而在这个多元化的内容生态中,好家风短视频以其独特的价值和…

5.透明效果

实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道(Alpha channel)。 当一个物体被渲染到屏幕上时,每个片元除了颜色和深度值之外,它还有另一个属性—透明度。 当透明度为1时,表示该像素是完…

Dvws靶场

文章目录 一、XXE外部实体注入二、No-SQL注入三、Insecure Direct Object Reference四、Mass Assignment五、Information Disclosure六、Command Injection七、SQL注入 一、XXE外部实体注入 访问http://192.168.92.6/dvwsuserservice?wsdl,发现一个SOAP服务。在SO…

MySQL 存储过程(二)

本篇继续介绍MySQL存储过程的相关内容。 目录 一、if语句 二、case 三、循环语句 while loop repeat 一、if语句 在存储过程中,可以使用if语句进行条件判断,其语法结构如下: if 判断语句 then 逻辑语句..... elseif 判断语句 then 逻…

【Linux取经路】初识信号

文章目录 一、人眼中的信号 VS 进程眼中的信号二、ctrlc 终止一个前台进程三、查看信号信息3.1 Core dump——核心转储功能验证 四、信号的处理方式五、ctrlc 被解释成2号信号验证5.1 signal——设置自定义捕捉方法 六、ctrlc 是如何变成信号的?七、异步、软中断八、…

【SQL边干边学系列】04中级问题(续)

文章目录 前言回顾中级问题25.高昂运费26.2015年的高昂运费27.高昂运维 - 使用between28.去年的高昂运费29.库存清单30.没有任何订单的客户31.没有任何订单的客户,员工ID为4 答案25.高昂运费26.2015年的高昂运费27.高昂运维 - 使用between28.去年的高昂运费29.库存清…

CVE-2022-4230

CVE-2022-4230 漏洞介绍 WP Statistics WordPress 插件13.2.9之前的版本不会转义参数,这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下,具有管理选项功能 (admin) 的用户可以使用受影响的功能,但是该插件有一个设置允许低权限用…

DDMA信号处理以及数据处理的流程---DDMA原理介绍

Hello,大家好,我是Xiaojie,好久不见,欢迎大家能够和Xiaojie一起学习毫米波雷达知识,Xiaojie准备连载一个系列的文章—DDMA信号处理以及数据处理的流程,本系列文章将从目标生成、信号仿真、测距、测速、cfar…

vscode设置代码自动换行显示

☆ 问题描述 vscode设置代码自动换行显示 ★ 解决方案 ✅ 总结

每日两题 / 198. 打家劫舍 74. 搜索二维矩阵(LeetCode热题100)

198. 打家劫舍 - 力扣(LeetCode) dp[i]表示考虑前i 1号房屋,能获取的最大金额。对于没一间房屋都有偷与不偷两种选择 如果偷,需要从dp[i - 2]转移,因为不能偷窃相邻房屋,dp[i] dp[i - 2] nums[i] 如果…

稍微学学react

文章开始前,先划划水~ 今日份开心: 今天看之前发布的按钮npm包下载量有162次,早知道好好做了 今日份不开心: 爬岗位看到一个整体都挺满意的岗位,公司位置和发展大方向都好喜欢!!!…

【PL理论】(6) F#:标准库之列表(List)

​​​​​ 💭 写在前面:本章我们将介绍 F# 标准库的列表,我们将简单的先过一遍列表的一些常用操作,具体的讲解我们将放在后续章节。 目录 0x00 标准库:列表(List) 0x01 模式匹配与列表 0x…

14.8k Star!CrewAI:部署一支由你指挥的人工智能代理大军,股票分析、发布帖子、支持Ollama!

原文链接:(更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号!) 14.8k Star!CrewAI:部署一支由你指挥的人工智能代理大军,股票分析、发布帖子、支持Ollama!…

计算机组成结构—多处理器

目录 一、SISD、SIMD、MIMD 和向量处理器 1. 费林分类法 2. SIMD 和向量处理器 二、硬件多线程 三、多核处理器和 SMP 1. 多核处理器 2. 共享内存多处理器(SMP) 3. MPP 和集群 一、SISD、SIMD、MIMD 和向量处理器 通过改进系统结构,可…

C++设计模式-外观模式,游戏引擎管理多个子系统,反汇编

运行在VS2022,x86,Debug下。 30. 外观模式 为子系统定义一组统一的接口,这个高级接口会让子系统更容易被使用。应用:如在游戏开发中,游戏引擎包含多个子系统,如物理、渲染、粒子、UI、音频等。可以使用外观…