1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. /**
  5. * 含头节点双向链表定义及有关操作
  6. */
  7.  
  8. //操作函数用到的状态码
  9. #define TRUE 1;
  10. #define FALSE 0;
  11. #define OK 1;
  12. #define ERROR 0;
  13.  
  14. //Status是新定义的一种函数返回值类型,其值为int型,意义为函数结果 状态码
  15. typedef int Status;
  16. //定义一种 数据元素 类型,为表示方便,定义为char型
  17. typedef char ElemType;
  18.  
  19. //双向链表的定义
  20. typedef struct DuLnode {
  21. ElemType data;
  22. struct DuLnode *next,*prior;
  23. } DuLnode, *DuLinkList;
  24.  
  25. //操作1:双向链表初始化
  26. Status InitList(DuLinkList *list){
  27. (*list)=(DuLinkList)malloc(sizeof(DuLnode));
  28. (*list)->prior=NULL;
  29. (*list)->next=NULL;
  30. return OK;
  31. }
  32.  
  33. //操作2:头插法建立双向链表,数据保存在ElemType类型的数组中
  34. Status CreateList_H(DuLinkList *list,ElemType arrData[],int length){
  35. int j;
  36. for(j=length-1;j>=0;j--){
  37. //新建结点并分配空间
  38. DuLnode *node;
  39. node=(DuLnode*)malloc(sizeof(DuLnode));
  40. node->data=arrData[j];
  41. node->prior=NULL;
  42. node->next=NULL;
  43.  
  44. //插入为1号结点
  45. node->next=(*list)->next;
  46. node->prior=(*list);
  47. if((*list)->next){ //第一个结点已存在
  48. (*list)->next->prior=node;
  49. }
  50. (*list)->next=node;
  51. }
  52. return OK;
  53. }
  54.  
  55. //操作3:尾插法建立双向链表
  56. Status CreateList_R(DuLinkList *list,ElemType arrData[],int length) {
  57. int j;
  58. DuLnode *r; //尾指针
  59. r=*list;
  60. for(j=0;j<length;j++) {
  61. DuLnode *node;
  62. node=(DuLnode*)malloc(sizeof(DuLnode));
  63. node->data=arrData[j];
  64. node->prior=NULL;
  65. node->next=NULL;
  66.  
  67. //插入表尾
  68. r->next=node;
  69. node->prior=r;
  70. r=node; //r指向尾结点
  71. }
  72. return OK;
  73. }
  74.  
  75. //操作4:双向链表元素遍历输出
  76. Status ListTraverse(DuLinkList list) {
  77. DuLnode *p;
  78. p=list;
  79. int j=0;
  80. printf("逻辑索引: 结点数据:\n");
  81. while(p->next){
  82. j++;
  83. p=p->next;
  84. printf(" %d %c\n",j,p->data);
  85. }
  86. return OK;
  87. }
  88.  
  89. //操作5:插入新元素数据到指定位置。(i为逻辑位置)
  90. Status ListInsert(DuLinkList *list,int i,ElemType elem){
  91. if(i<1) return ERROR; //插入位置序号小于1
  92. DuLnode *p;
  93. int j=0; //计数器
  94. p=*list;
  95. //先找到第i-1个结点
  96. while(p&&j<i-1){
  97. j++;
  98. p=p->next;
  99. }
  100. if(!p) return ERROR;
  101.  
  102. //构造新结点
  103. DuLnode *new_node;
  104. new_node=(DuLnode*)malloc(sizeof(DuLnode));
  105. new_node->data=elem;
  106.  
  107. //插入到链表
  108. if(p->next){ //当i!=length+1时,即非插入尾结点之后时。
  109. new_node->next=p->next;
  110. p->next->prior=new_node;
  111. }
  112. new_node->prior=p;
  113. p->next=new_node;
  114.  
  115. return OK;
  116. }
  117.  
  118. //操作6:删除链表第i个结点,被删除的数据保存在elem
  119. Status ListDelete(DuLinkList *list,int i,ElemType *elem){
  120. if(i<1) return ERROR;
  121. DuLnode *p; //工作指针指向待删结点
  122. int j=1; //计数器
  123. p=(*list)->next; //指向首元
  124. while(p&&j<i) {
  125. p=p->next;
  126. j++;
  127. }
  128. if(!p) return ERROR; //i>length
  129.  
  130. //删除结点
  131. p->prior->next=p->next;
  132. if(p->next){
  133. p->next->prior=p->prior; //若删除的不是尾结点
  134. }
  135.  
  136. free(p);
  137. return OK;
  138. }
  139.  
  140. //其他操作(如:判空、销毁、清空、求表长、按值查找、遍历输出、索引到数据等)由于不涉及或只涉及一个方向,故与单链表的操作无异。
  141.  
  142. int main(void){
  143. //定义一个双向链表(用指针list1表示)
  144. DuLinkList list1;
  145.  
  146. //链表初始化
  147. Status initResultCode=InitList(&list1);
  148. printf("list1初始化结果:%d\n",initResultCode);
  149.  
  150. //产生数据并保存到数组
  151. ElemType data1='A',data2='B',data3='C',data4='D',data5='E',data6='F';
  152. ElemType waitInserted[]={
  153. data1,
  154. data2,
  155. data3,
  156. data4,
  157. data5,
  158. data6,
  159. };
  160. //获得数组长度
  161. int arrLength=sizeof(waitInserted)/sizeof(waitInserted[0]);
  162.  
  163. //头插法建立链表list1
  164. Status createListResult1 = CreateList_H(&list1,waitInserted,arrLength);
  165. printf("建表结果状态码:%d\n",createListResult1);
  166. ListTraverse(list1); //遍历测试
  167.  
  168. //定义表2
  169. DuLinkList list2;
  170. InitList(&list2);
  171. //尾插法建立链表list2
  172. CreateList_R(&list2,waitInserted,arrLength);
  173. ListTraverse(list2); //遍历测试
  174.  
  175. //插入结点
  176. ElemType elemInserted='T';
  177. Status insertResultCode = ListInsert(&list1,1,elemInserted);
  178. printf("插入结果状态码:%d\n",insertResultCode);
  179. ListTraverse(list1); //遍历测试
  180.  
  181. //删除结点,并保存删除的数据
  182. ElemType deletedElem;
  183. Status deleteResultCode=ListDelete(&list1,2,&deletedElem);
  184. printf("删除结果状态码:%d\n",deleteResultCode);
  185. printf("被删除结点数据:%c\n",deletedElem);
  186. ListTraverse(list1); //遍历测试
  187.  
  188. printf("\nEND!");
  189. return 0;
  190. }

双向链表及有关操作(C语言)的更多相关文章

  1. 双向链表的实现与操作(C语言实现)

    双向链表也叫双链表,是链表的一种,它的每一个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的随意一个结点開始,都能够非常方便地訪问它的前驱结点和后继结点. 单链表的局限 1.单 ...

  2. neo4j初次使用学习简单操作-cypher语言使用

    Neo4j 使用cypher语言进行操作 Cypher语言是在学习Neo4j时用到数据库操作语言(DML),涵盖对图数据的增删改查  neo4j数据库简单除暴理解的概念: Neo4j中不存在表的概念, ...

  3. 栈的实现与操作(C语言实现)

    栈的定义  1, 栈是一种特殊的线性表  2,栈仅能在线性表的一端进行操作  3,栈顶(Top): 同意操作的一端 同意操作的一端  4,栈底(Bottom): ,不同意操作的一端 不同意操作 ...

  4. 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...

  5. 1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 ? 1 2 3 4 5 6 7 8 9 10 11 12 package main   imp ...

  6. 【C语言教程】双向链表学习总结和C语言代码实现!值得学习~

    双向链表 定义 我们一开始学习的链表中各节点中都只包含一个指针(游标),且都统一指向直接后继节点,通常称这类链表为单向链表. 虽然使用单向链表能 100% 解决逻辑关系为 "一对一" ...

  7. 动态单链表的传统存储方式和10种常见操作-C语言实现

    顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. ...

  8. Gremlin--一种支持对图表操作的语言

    Gremlin 是操作图表的一个非常有用的图灵完备的编程语言.它是一种Java DSL语言,对图表进行查询.分析和操作时使用了大量的XPath. Gremlin可用于创建多关系图表.因为图表.顶点和边 ...

  9. 动态分配的顺序线性表的十五种操作—C语言实现

    线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点 ...

随机推荐

  1. 杭电多校HDU 6579 Operation (线性基 区间最大)题解

    题意: 强制在线,求\(LR\)区间最大子集异或和 思路: 求线性基的时候,记录一个\(pos[i]\)表示某个\(d[i]\)是在某个位置更新进入的.如果插入时\(d[i]\)的\(pos[i]\) ...

  2. Redis五大类型及底层实现原理

    目录 简单动态字符串链表字典跳跃表整数集合压缩列表对象 对象的类型与编码字符串对象列表对象哈希对象 集合对象有序集合对象类型检查与命令多态内存回收对象共享对象的空转时长 简单动态字符串  导读 Red ...

  3. Vue 面试题汇总

    Vue 面试题汇总 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  4. IT-ebooks free download website & IT 电子书籍免费下载网站

    free ebooks of programming 1. http://www.it-ebooks.info/ http://www.it-ebooks-api.info/ 2. http://ww ...

  5. 前端 Web 异常监控系统 All In One

    前端 Web 异常监控系统 All In One Sentry https://sentry.io trackjs https://trackjs.com/ rollbar https://rollb ...

  6. js & regex & var & highlight

    js & regex & var & highlight let key = `ali`.toLocaleUpperCase(); let name = "阿里云计算 ...

  7. svn conflict & svn cleanup

    svn conflict & svn cleanup OK $ svn --help $ svn cleanup Tree Conflicts https://tortoisesvn.net/ ...

  8. Web 安全 & 反爬虫原理

    Web 安全 & 反爬虫原理 数据加密/解密 HTTPS ip 封锁 请求限制 爬虫识别,canvas 指纹 refs https://segmentfault.com/a/119000001 ...

  9. 什么是NGK算力挖矿?怎么使用USDN购买算力?

    NGK公链项目即将正式上线,NGK项目中重要生态NGK算力挖矿也将启动,正式开启DPOSS挖矿.因为具有低能耗,低搭建费用,高收益等特点,可以想象如果正式上线必将引起行业瞩目. NGK算力挖矿项目为N ...

  10. HTTP 1.x 学习笔记 —— Web 性能权威指南

    HTTP 1.0的优化策略非常简单,就一句话:升级到HTTP 1.1.完了! 改进HTTP的性能是HTTP 1.1工作组的一个重要目标,后来这个版本也引入了大量增强性能的重要特性,其中一些大家比较熟知 ...