当前位置: 首页 > news >正文

探索双链表:C语言中的链式结构魔法

目录

引言

一、双链表基础

1.1、什么是双链表?

1.2、双链表节点的结构定义

二、双链表的基本操作

2.1、双链表的初始化

2.2、尾插法

2.3、头插

2.4、判断双链表是否为空

2.5、尾删法

2.6、头删法

2.7、查找

2.8、双链表在指定位置之前插入

2.9、双链表删除指定节点

2.10、双链表的销毁

三、总结

结语


引言

在程序设计中,数据结构扮演着至关重要的角色。链表作为一种基础且强大的数据结构,广泛应用于需要动态内存管理和高效插入删除的场景。而双链表作为链表的一种拓展,具有双向遍历的能力,为我们的算法设计提供了更大的灵活性。本篇博客将带你深入了解C语言中的双链表,包括其定义、基本操作以及实际应用,让你在掌握数据结构的同时,提高编程的效率与能力

一、双链表基础

1.1、什么是双链表?

双链表同单链表一样,是一种线性结构的数据结构,与单链表不同的是,双链表的每个节点有两个指针,分别指向下一个节点和上一个节点。这使得双链表既可以向前遍历,也可以向后遍历,极大的节省了时间,但代价就是每个节点所占用的空间变大了。

1.2、双链表节点的结构定义

typedef int DLElemType;
typedef struct DListNode
{DLElemType data;   //节点的数据域struct DListNode* next;   //指向下一个节点struct DListNode* prev;   //指向上一个节点
}DListNode;

二、双链表的基本操作

2.1、双链表的初始化

void DLInit(DListNode** pphead)
{*pphead = (DListNode*)malloc(sizeof(DListNode));if (*pphead == NULL){perror("malloc fail!");exit(1);}(*pphead)->data = 0;(*pphead)->next = (*pphead)->prev = *pphead;
}

这里要注意的是,为了与其他类型的链表区分,双链表的初始化让两个指针都指向自己

2.2、尾插法

void DLPushBack(DListNode* phead , DLElemType x)
{assert(phead);DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = phead;newnode->prev = phead->prev;phead->prev->next = newnode;phead->prev = newnode;
}

在单链表中,我们要进行尾差就必须遍历找到最后一个节点,但是在双链表中,我们只需要找到头结点的prev指向就可以了,非常的方便

2.3、头插

在此之前,我们需要编写一个函数来实现新节点的创建,一次来提高效率:

//创建一个新的双链表节点
DListNode* BuyDListNode(DLElemType x)
{DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = newnode->prev = NULL;return newnode;
}

接下来就是头插法的实现了

//头插
void DLTPushFront(DListNode* phead, DLElemType x)
{assert(phead);DListNode* newnode = BuyDListNode(x);newnode->prev = phead;newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;
}

2.4、判断双链表是否为空

//判断双链表是否为空
bool DLTEmpty(DListNode* phead)
{assert(phead);return phead->next == phead;
}

2.5、尾删法

void DLTPopBack(DListNode* phead)
{assert(phead && !DLTEmpty(phead));DListNode* pcur = phead->prev;pcur->prev->next = phead;phead->prev = pcur->prev;free(pcur);pcur = NULL;
}

2.6、头删法

void DLTPopFront(DListNode* phead)
{assert(phead && !DLTEmpty(phead));DListNode* pcur = phead->next;phead->next = pcur->next;pcur->next->prev = phead;free(pcur);pcur = NULL;
}

2.7、查找

DListNode* DLTFind(DListNode* phead, DLElemType x)
{assert(phead && !DLTEmpty(phead));DListNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x){return pcur;}pcur = pcur->next;}return NULL;
}

2.8、双链表在指定位置之前插入

void DLTInsert(DListNode* pos, DLElemType x)
{assert(pos);DListNode* newnode = BuyDListNode(x);newnode->next = pos;newnode->prev = pos->prev;pos->prev->next = newnode;pos->prev = newnode;
}

2.9、双链表删除指定节点

void DLTErase(DListNode* pos)
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

2.10、双链表的销毁

void DLTDestory(DListNode** pphead)
{assert(pphead && *pphead);DListNode* pcur = (*pphead)->next;while (pcur != *pphead){DListNode* tmd = pcur->next;free(pcur);pcur = tmd;}free(*pphead);*pphead = NULL;
}

三、总结

掌握了单链表,那么掌握双链表也是分分钟的事,本篇以有哨兵位,循环的双链表为目的编写的代码。双链表的实际应用广泛,例如播放器的歌曲上一首下一首 ,以及网页的进一步退一步等。双链表非常好掌握,这里就不多赘述了

结语

通过对双链表的系统讲解与实践操作,相信你已经对其核心思想与实现细节有了更深的理解。双链表不仅是数据存储的利器,更是算法设计中不可或缺的基础结构。在今后的学习与开发中,灵活运用双链表,将会让你的代码更加高效、优雅。希望这篇文章能为你打开链式结构世界的大门,助你在编程之路上越走越远!

http://www.dtcms.com/a/295815.html

相关文章:

  • 光谱仪杂散光性能分析
  • 大疆无人机炸机后视频损坏的完美修复案例解析
  • uni-file-picker vue3二次封装(本地上传 + v-model)
  • Mysql命令show processlist
  • Linux基础服务(autofs和Samba)
  • 论文阅读:《针对多目标优化和应用的 NSGA-II 综述》一些关于优化算法的简介
  • OpenCV —— color_matrix_numpy_mat_reshape
  • 新mac电脑软件安装指南(前端开发用)
  • 解决http的web服务中与https服务交互的问题
  • 平时遇到的错误码及场景?404?400?502?都是什么场景下什么含义,该怎么做 ?
  • AI实践:Pydantic
  • 大模型Prompt优化工程
  • pdf文件的属性值怎么修改?修改PDF内部的属性创建时间和修改时间
  • Lua(垃圾回收)
  • omofun官网网站入口,动漫在线看|官方下载
  • AI服务器给一体成型电感带来多大的市场空间
  • 网络编程——聊天程序实现
  • FreeSWITCH 简单图形化界面45 - 收集打包的一些TTS
  • 复矩阵与共轭转置矩阵乘积及其平方根矩阵
  • 【建模与仿真】融合共现网络特征与知识增强语义梯度提升电子邮件分类
  • HttpServletRequest深度解析:Java Web开发的核心组件
  • LLM中的位置嵌入矩阵(Position Embedding Matrix)是什么
  • [语言模型训练]基于 PyTorch 的双向 LSTM 文本分类器实现:基于旅店的评论分类语言模型
  • LeetCode 2563.统计公平数对的数目
  • Edwards爱德华泵软件 支持nEXT85和nXDS系列泵,包括nXRi, nRVi和nXLi增强型 nEXT nXDS nXLi
  • 【自动化测试】JMeter+Jenkins自动化接口与性能测试环境部署指南
  • Java学习第七十部分——微服务架构
  • JavaWeb_原始项目初识(一)
  • ubuntu25.04+4070+cuda+docker安装
  • 进程通信————命名管道