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

数据结构-2.9.双链表

一.双链表与单链表的对比:


二.双链表的初始化(带头结点):

1.图解:

2.代码演示:

#include<stdio.h>
#include<stdlib.h>
​
//定义双链表结构体
typedef struct DNode
{
    int data;
    struct DNode *prior;//前驱指针即指向前面数据的指针 
    struct DNode *next;//后继指针即指向后面数据的指针 
}DNode,*DLinklist; //DLinklist与DNode *等价,DLinklist强调链表,DNode *强调结点 
​
//初始化双链表
bool InitDLinkList(DLinklist &L)
{
    L = (DNode *)malloc( sizeof(DNode) );//分配一个头结点
    if( L==NULL ) //内存不足,分配失败 
    {
        return false;
    } 
    L->prior = NULL;//头结点的prior(前驱)永远指向NULL
    L->next = NULL;//头结点之后(后继)暂时还没有结点 
    return true;
} 
​
//判断双链表是否为空(带头结点)->只需要看第一个结点是否为空即可 
bool Empty(DLinklist L)
{
    if( L->next == NULL )//代表双链表第一个结点为空,是空双链表
    {
        return true;
    }
    else
    {
        return false;//代表双链表第一个结点不为空,不是空双链表 
    }
} 
​
int main()
{
    //初始化双链表 
    DLinklist L;
    InitDLinkList(L);
    //后续代码。。。 
    return 0;
}

三.双链表的插入:

图解:

此时要p结点之后插入s结点,起初p->next指向y,先把p的下一个结点即y和要插入的结点即s的指向下一个结点的指针对接即s->next = p->next:

之后还需要把p结点的后继结点即p->next的前向指针p->next->prior指向s即p->next->prior = s:

再把要插入的结点即s结点的前驱指针指向p结点即 s->prior = p:

最后把p结点的后继结点指向s即p->next = s:

但对于上述代码,有一个bug,当p结点是最后一个结点时,p->next->prior = s就会报空指针的错,因为

p结点是最后一个结点时p->next指向NULL,因此,严谨的代码如下:对p->next进行空指针判断

  • 按位序插入:找到要插入的位序的前驱结点,在该结点实现后插操作即可

  • 前插操作:由于双链表的特性,可以很方便的找到给定结点的前驱结点,再对前驱结点进行后插操作即可


四.双链表的删除:

图解:

此时要删除p结点的后继结点q,因此要把q结点的下一个结点和p结点连接,即p->next = q->next:

再把要删除的q结点的后继结点即q->next的前驱结点即q->next->prior指向p即q->next->prior = p:

最后再释放要删除的q结点即free(q):free函数要用到头文件#include<stdlib.h>

但上述代码也有bug,如果此时要删除的q结点为双链表最后一个结点,那么q->next就指向NULL,q->next->prior就会报空指针错误,因此对q->next进行空指针判断以增加严谨性:

销毁双链表:每一次删除头结点的后继结点即可

因为比如第一次删除头结点的后继结点即第一个结点,第二次删除时第二个结点就来了第一个位置,相当于头结点的后继结点,删除即可,以此类推,可销毁双链表:


五.双链表的遍历:

1.对于前向遍历(跳过头结点)的循环条件当p->prior == NULL时,说明此时p结点指向的就已经是头结点了,此时跳出循

环,不操作头结点了;

2.对于按位查找,只需要添加一个计数器,用于记录此时指向的哪个位置的元素,当位置和要找的位置匹配时打印即可;

3.对于按值查找,只需要对当前指向的结点和要找的值对比即可,找到了就打印即可;

4.双链表没有随机存取的特性,所以按位查找,按值查找的时间复杂度为O(n),因为只能用循环的方式一个一个对比依次

往后找。


六.总结:



http://www.kler.cn/a/313182.html

相关文章:

  • 浅谈:基于三维场景的视频融合方法
  • 鸿蒙学习基本概念
  • 大厂的 404 页面都长啥样?看看你都见过吗~~~
  • 阿里云和七牛云对象存储区别和实现
  • 【最新版】Stable Diffusion4.9(AI绘画)下载及安装教程(附软件安装包)!
  • DHCP与FTP
  • 周末愉快!——周复盘
  • 深度学习-03 Pytorch
  • Android 空气质量刻度
  • CleanClip For Mac 強大的剪貼簿助手Paste替代工具 v2.2.1
  • 学习笔记——EffcientNetV2
  • React——点击事件函数调用问题
  • Gradio离线部署到内网,资源加载失败问题(Gradio离线部署问题解决方法)
  • docker搭建个人网盘,支持多种格式,还能画图,一键部署
  • Matlab可视化│常用绘图全家桶
  • HTTP中的301、302实现重定向
  • ActivityManagerService 分发广播(6)
  • Vue3:reactive丢失响应式,数据有更新但表单没有更新
  • gin配置swagger文档
  • 树与图的深度优先遍历(dfs的图论中的应用)
  • 【CPP】类与继承
  • [原创]全新安装最新版Delphi 12.2之前, 如何正确卸载旧版Delphi 12.1?
  • 谈对象第二弹: C++类和对象(中)
  • SQLiteHelper
  • Java:List<String> 转换List<BigDecimal> 并求和
  • Hadoop-MapReduce的 原理 | 块和片 | Shuffle 过程 | Combiner