《数据结构和算法》之双向链表
来源:互联网 发布:淘宝店铺怎么加入淘客 编辑:程序博客网 时间:2024/05/16 16:14
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
怎样理解双向链表,用生活中的一个例子来解释一下:最开始的火车是只有一个火车头的,当一辆火车从A->B->C->D->E->F->G->H->J->K->L这条路线进行行驶,假设或者运行到H站点要运送一批货物到G站点,只能通过H->J->K->L->A->B->C->D->F->G这个路线来进行,相当于是单向循环链表的形式。这个时候大家可以看到很费时和费力,严重的浪费时间和资源,这个时候人们就想了,如果火车可以倒着走那不就很方便吗,于是火车慢慢地开始有了两个火车头,这样可以往后走,直接后退一个站点,这样就可以轻松实现K->G的运输工作。这个小例子就类似于双向链表,但是真正意义上的双向链表跟这个又是有一点的区别,那么这个时候相对于单链表而言。双向链表就可以定义如下的结构体:
typedef struct DualNode{ElemType data;struct DualNode *prior; //前驱结点struct DualNode *next; //后继结点 }DualNode, *DuLinkList;
如下图1,双向链表的结点结构示意图以及空链表的结构示意图
图1 双向链表结点结构图
在图1中可以看到,结点结构比之前的单链表多了一个结点,多一个头指针prior,存放着前驱结点的指针,当双向链表的两个结点都为空的时候则为空链表。
图2 非空的双向循环链表
对于非空双向链表中的一个结点p,它的后继结点的前驱结点是什么? 当然就是它自己。
2,双向链表的插入操作
图3 可以看到双向循环链表的插入操作
在图3中可以看到具体的操作步骤,具体代码实现如下:
s->next = p;s->prior = p->prior;p->prior->next = s;p->prior = s;
这四步分别对应着图3中的四步操作,首先将s结点的后继指针指向p;接着将s的前驱结点赋值为p的前驱指针;p的前驱结点的后继结点赋值为s;最后将p的前驱结点赋值为s。
3,双向链表的删除操作
图4 删除操作
在图4中可以看到,直接将前一个元素的后继指针指向后一个元素的前驱结点,同时将后一个元素的前驱结点指向前一个元素的前驱结点。代码即为:
p->prior->next = p->next;p->next->prior = p->prior;free(p);
4,与单链表的区别
(1)从任意一个结点开始,可以查找链表中的其他任意结点。
(2)既可以依照后继的方向(向后)遍历,也可以依照前驱的方向(向前)遍历。
(3)每个指针域中都增加了一个存储指针的空间,降低了存储密度。
(4)可以在当前结点前面或者后面插入,可以删除前趋和后继(包括结点自己)。 单链表只能在结点后面插入和删除。
(5)双向链表通过增加一定的空间复杂度,降低了向前遍历的时间复杂度。
- 《数据结构和算法》之双向链表
- 《数据结构和算法》之双向链表问题实践
- 算法与数据结构之双向链表
- 算法学习之数据结构之双向链表
- 数据结构与算法之六 双向链表和循环链表
- 算法与数据结构之四----双向链表
- "双向链表"-数据结构算法-之通俗易懂,完全解析
- 数据结构与算法之双向链表 <二>
- 数据结构和算法系列 - 双向链表结构
- 双向链表的算法设计和实现(数据结构)
- 数据结构和算法C++语言实现:双向链表
- Java数据结构和算法-链表(4-双向链表)
- 数据结构之双向链表
- 数据结构之双向链表
- 数据结构之双向链表
- 数据结构之双向链表
- 数据结构之双向链表
- 数据结构之双向链表
- 操作系统之页面置换算法
- 求素数Java实现
- 综合转载文章列表
- 一些关于树的知识杂项
- 文本特征提取_01:词项文档矩阵
- 《数据结构和算法》之双向链表
- PAT算法笔记(十五)————D进制的A+B
- 响应式网格(栅格化)布局
- Linux进程间通信(IPC)之综述
- tableView实现二级菜单
- ORA-01841: (完整) 年份值必须介于 -4713 和 +9999 之间, 且不为 0情况解决
- NoSQL中的行存储与列存储
- 如何在Ubuntu 14.04上安装Elasticsearch、Logstash以及Kibana(即ELK堆栈)
- 6种负载均衡算法