双向链表主要为了解决单链表找前驱的问题。除了插入、删除操作之外,其他操作与单链表都相同。因此这里只是比较简单的写了双向链表的插入和删除操作。画出结点结构图的话,思路会很清晰,线性表这块还算是比较简单的能够实现。

  1 /*
  2     在单链表中,求后继的方法NextElem执行的时间为O(1),求前驱的方法PriorElem执行的时间为O(n),
  3     引入双向链表就是为了克服单链表这种单向性的缺点。
  4 */
  5
  6 #include<stdio.h>
  7 #include<stdlib.h>
  8
  9 //定义存储类型
 10 typedef int ElemType;
 11
 12 //双向链表的存储结构
 13 typedef struct DuLNode{
 14     ElemType data;
 15     DuLNode *next;
 16     DuLNode *prior;
 17 }DuLNode, *DuLinkList;
 18
 19 //声明,指针函数
 20 void(*visit)(DuLNode *node);
 21
 22 //声明,辅助函数
 23 void visitData(DuLNode *node);
 24
 25 //对双向链表的基本操作
 26 bool InitDuLinkList(DuLinkList &L);    //    初始化一个空表
 27 DuLinkList GetLNode(DuLinkList L, int i);    //返回第i个结点
 28 void ListTraverse(DuLinkList L, void(visit(DuLNode *node)));    //遍历双向链表
 29 void ListInsert(DuLinkList &L, int i, ElemType e);    //在第i个结点之前插入,数据域是e的结点
 30 void AppendLast(DuLinkList &L, ElemType e);    //在最后一个结点之后插入,数据域是e的结点
 31 void ListDelete(DuLinkList &L, int i, DuLinkList &rNode);    //删除第i个结点并返回
 32
 33 //测试模块
 34 int main(){
 35
 36     DuLinkList L;
 37     InitDuLinkList(L);
 38     for (int i = 1; i <= 6; i++)
 39         AppendLast(L, i);
 40     ListTraverse(L, visitData);
 41     printf("\n");
 42
 43     printf("第一个元素的后继是:%d\n", GetLNode(L, 1)->next->data);
 44     printf("第一个元素的前驱是:%d\n", GetLNode(L, 1)->prior->data);
 45     printf("最后一个元素的前驱是:%d\n", GetLNode(L, 6)->prior->data);
 46     printf("\n");
 47
 48     ListInsert(L, 1, 7);
 49     ListTraverse(L, visitData);
 50     printf("第一个元素的后继是:%d\n", GetLNode(L, 1)->next->data);
 51     printf("第一个元素的前驱是:%d\n\n", GetLNode(L, 1)->prior->data);
 52
 53     DuLNode *rNode;
 54     ListDelete(L, 7, rNode);
 55     ListTraverse(L, visitData);
 56     printf("最后一个元素的前驱是:%d\n", GetLNode(L, 6)->prior->data);
 57     ListDelete(L, 1, rNode);
 58     ListTraverse(L, visitData);
 59     printf("第一个元素的后继是:%d\n", GetLNode(L, 1)->next->data);
 60     printf("第一个元素的前驱是:%d\n\n", GetLNode(L, 1)->prior->data);
 61
 62     system("pause");
 63     return 0;
 64 }
 65
 66 //各函数定义模块
 67 void visitData(DuLNode *node){
 68     printf("%4d", node->data);
 69 }
 70
 71 bool InitDuLinkList(DuLinkList &L){    //    初始化一个空表
 72     L = (DuLinkList)malloc(sizeof(DuLNode));
 73     if (!L)
 74         return false;
 75     L->prior = NULL;
 76     L->next = NULL;
 77     return true;
 78 }
 79
 80 DuLinkList GetLNode(DuLinkList L, int i){    //返回第i个结点的值
 81     int j = 1;
 82     DuLNode *p = L->next;
 83
 84     //找第i个结点
 85     while (p && j != i){
 86         p = p->next;
 87         j++;
 88     }
 89
 90     if (j > i || !p){
 91         printf("\n不存在该结点!\n");
 92         return L;
 93     }
 94
 95     return p;
 96 }
 97
 98 void ListTraverse(DuLinkList L, void(visit(DuLNode *node))){    //遍历单链表
 99     DuLNode *p = L->next;
100     while (p){
101         visit(p);
102         p = p->next;
103     }
104     printf("\n");
105 }
106
107 void ListInsert(DuLinkList &L, int i, ElemType e){    //在第i个结点之前插入,数据域是e的结点
108     DuLNode *p = GetLNode(L, i);
109     if (!p){
110         printf("没找到该元素,不能进行插入!\n");
111         return;
112     }
113
114     DuLNode *s = (DuLinkList)malloc(sizeof(DuLNode));
115     if (!s)
116         return;
117     s->data = e;
118     s->next = p;
119     p->prior->next = s;
120     s->prior = p->prior;
121     p->prior = s;
122 }
123
124 void AppendLast(DuLinkList &L, ElemType e){    //在最后一个结点之后插入,数据域是e的结点
125     //找到最后一个结点
126     DuLNode *p = L;
127     while (p->next){
128         p = p->next;
129     }
130     //新建一个结点
131     DuLNode *newNode = (DuLinkList)malloc(sizeof(DuLNode));
132     if (!newNode)
133         return;
134     newNode->data = e;
135     //插入
136     newNode->next = p->next;
137     p->next = newNode;
138     newNode->prior = p;
139 }
140
141 void ListDelete(DuLinkList &L, int i, DuLinkList &rNode){    //删除第i个结点并返回
142     DuLNode *p = GetLNode(L, i);
143     if (!p){
144         printf("没找到该元素,不能进行删除!\n");
145         return;
146     }
147
148     p->prior->next = p->next;
149     if (p->next){
150         p->next->prior = p->prior;
151         p->next = NULL;
152         p->prior = NULL;
153     }
154
155     rNode = p;
156     free(p);
157 }

转载于:https://www.cnblogs.com/yangxiaohe/p/6280208.html

数据结构——双向链表的实现相关推荐

  1. 数据结构 — 双向链表

    目录 文章目录 目录 双向链表 双向链表结点的数据结构 双向链表的操作集合 应用示例 创建双向链表 清理双向链表 查询链表结点 更新链表结点的数据 插入链表结点 删除结点 打印链表数据 双向链表 双向 ...

  2. 数据结构 —— 双向链表(超详细图解 接口函数实现)

    系列文章目录 数据结构 -- 顺序表 数据结构 -- 单链表 数据结构 -- 双向链表 数据结构 -- 队列 数据结构 -- 栈 数据结构 -- 堆 数据结构 -- 二叉树 数据结构 -- 八大排序 ...

  3. python 双向链表_数据结构-双向链表(Python实现)

    数据结构在编程世界中一直是非常重要的一环,不管是开发还是算法,哪怕是单纯为了面试,数据结构都是必修课,今天我们介绍链表中的一种--双向链表的代码实现. 好了,话不多说直接上代码. 双向链表 首先,我们 ...

  4. python程序实现双向链表_数据结构-双向链表(Python实现)

    数据结构在编程世界中一直是非常重要的一环,不管是开发还是算法,哪怕是单纯为了面试,数据结构都是必修课,今天我们介绍链表中的一种--双向链表的代码实现. 好了,话不多说直接上代码. 双向链表 首先,我们 ...

  5. Linux c 算法与数据结构--双向链表

    链表是linux c中非常重要的数据结构,双向链表与单向链表的区别,是它每个节点有两个指针域,分别指向该节点的前一个节点与后一个节点: 而链表的操作主要是查询.插入.删除.遍历等,下面来看一个双向链表 ...

  6. C语言数据结构双向链表之温故而知新

    单向链表:http://blog.csdn.net/morixinguan/article/details/77756216 单向链表理解了,那双向就非常简单了,没什么好说的,看图: 双链表的引入是为 ...

  7. 数据结构 | 双向链表

    一.数据结构定义 /* 链表结点 */ typedef int ListType; typedef struct node {ListType data; // 存放整型数据struct node* ...

  8. Linux内核分析--内核中的数据结构双向链表续【转】

    在解释完内核中的链表基本知识以后,下面解释链表的重要接口操作: 1. 声明和初始化 实际上Linux只定义了链表节点,并没有专门定义链表头,那么一个链表结构是如何建立起来的呢?让我们来看看LIST_H ...

  9. 数据结构-双向链表的实现

    题目: 1 双向升序链表结构定义如下: 2 class Node { 3 4 private int value;// 保存节点的数据 5 6 private Node pre, next;// 保存 ...

  10. 数据结构--双向链表

    双向链表的一种Go语言实现 package mainimport "fmt"//定义节点信息 type dNode struct {id intname stringpre *dN ...

最新文章

  1. Bootstrap:关于bootstrap单页面中多Modal的问题
  2. 高并发下redis缓存穿透问题解决方案
  3. 整体C#与Sql培训内容及结构
  4. Android通过adb命令传参给APP的方法
  5. php实现第三方邮箱登录_PHP实现用户异地登录提醒功能的方法
  6. phpcmsV9 QQ登录问题分析 - 踩坑篇
  7. Python(37)_字典嵌套
  8. hadoop配置(个人总结)
  9. JUNIT Hello World
  10. 打开stl文件_介绍一种修复、查看以及打印STL三维模型文件的工具
  11. 充分发挥计算机在教学中的辅助作,充分发挥计算机在教学中的辅助作用
  12. 为什么云原生+分布式是数据库的未来?
  13. 使用NoSQL Manager for MongoDB客户端连接mongodb
  14. 资源管理器和计算机的功能基本相同吗,“资源管理器”和“计算机”的功能基本相同...
  15. 需求分析和架构设计总结--利用DODAF方法
  16. mysql 随机取数组_sql语句实现随机取n条数据(转)
  17. 你还在对着手机干唱?k歌神器挑选法则
  18. IT创业光技术好,谋略定位不好,你很可能会死得很惨,丢钱、丢客户、丢成果、丢商机、丢思路
  19. python一只青蛙一次可以_Python算法题(一)——青蛙跳台阶
  20. 消费品与社区图腾:从 Coven 看女性向 PFP 市场

热门文章

  1. ubuntu下安装jre的步骤
  2. 一个sql题目, 统计每年每月的信息
  3. jrebel不能使用ajax,Jrebel不生效的原因和解决办法
  4. hive查勘表结构_Hive中的数据库、表、数据与HDFS的对应关系
  5. 逻辑漏洞之密码找回总结
  6. 字符串里解析vue表达式
  7. [编程题]表达式合法判断
  8. 领域驱动设计(DDD)的精髓
  9. Redis cluster原理
  10. BTrace简介及使用