当前位置:   article > 正文

数据结构(使用头插法实现双链表)_头插法建立双链表

头插法建立双链表

一.为什么使用双链表

答:单链表结点中只有一个后继指针,这使得单链表无法直接访问某个结点的前驱结点,只能从头结点开始依次顺序向后遍历,访问后继结点的时间复杂度为O(1),访问前驱结点的时间复杂度为O(n)。

为了克服单链表的不足,我们给每个结点增加指向前驱结点的前驱指针(这样每个结点就拥有了两个指针:前驱指针prior和后继指针next)

二.代码分块

1.定义双链表的结点类型

  1. typedef struct DNode{//定义双链表结点类型
  2. int Length;//长度
  3. int data;//数据域
  4. struct DNode *prior,*next;//前驱指针和后继指针
  5. }DNode,*DLinkList;

2.使用头插法创建双链表

  1. DLinkList BulidList(DLinkList DL){//使用头插法创建双链表
  2. DL = (DLinkList)malloc(sizeof(DNode));//分配一个头结点
  3. if(DL==NULL){//分配失败
  4. return false;
  5. }
  6. DL->Length=0;//初始化
  7. DL->data = 0;
  8. DL->next = NULL;
  9. DL->prior = NULL;
  10. int addNum;//定义添值变量
  11. printf("向链表输入初始值\n");
  12. printf("请输入要插入的内容:");
  13. scanf("%d",&addNum);//获取插入内容
  14. while(addNum!=99){
  15. DNode *addPoint; //创建一个指针
  16. addPoint = (DNode *)malloc(sizeof(DNode));//指向创建的新结点
  17. addPoint->data = addNum;//赋值
  18. addPoint->next = DL->next;//头插法
  19. addPoint->prior = DL;
  20. DL->next = addPoint;
  21. DL->Length++;
  22. printf("请再次输入要插入的内容:");
  23. scanf("%d",&addNum);//获取插入内容
  24. }
  25. return DL;
  26. }

 

 

3.遍历显示双链表的全部数据

  1. void ShowList(DLinkList DL){
  2. DNode *x;//定义一个指针
  3. int num = DL->Length;//num用于暂存该链表长度
  4. printf("该链表一共有%d个元素\n",num);
  5. // x = (LNode *)malloc(sizeof(LNode));
  6. x = DL;//将头结点的信息赋给x
  7. x = x->next;//跳过头结点,因为头结点不存储数据
  8. while(num>0){
  9. printf("%d\n",x->data);//输出该节点的数据
  10. x = x->next;//移向下一个结点
  11. num--;//遍历总数减一
  12. }
  13. }

4.按位查找数据元素

  1. LinkList GetElem(DLinkList DL,int findPos){//按位查找
  2. DNode *record;//定义一个遍历指针
  3. record = DL;//遍历指针指向双链表表头
  4. int x = 1;//记录位置变量赋初值1
  5. while(record!=NULL){//当双链表没有遍历结束时
  6. record = record->next;//指针指向下一个结点
  7. if(x==findPos){//当查找位置和当前位置一致时
  8. printf("%d值在链表的第%d结点",record->data,x);//输出结果
  9. return record;//返回要查找的结点
  10. }
  11. x++;//累加
  12. }
  13. printf("没有找到");
  14. return NULL;//没找到返回空
  15. }

  

 

5.按位插入数据元素

  1. bool InsertList(DLinkList DL,DNode *InsertPos,DNode *InsertPoint){//插入元素,输入:双链表,前驱结点,插入结点
  2. InsertPoint->next = InsertPos->next;//插入结点的后继指针指向前驱结点的后继结点
  3. InsertPos->next->prior=InsertPoint;//前驱结点原后继结点的前驱指针指向插入结点
  4. InsertPoint->prior = InsertPos;// 插入结点的前驱指针指向前驱结点
  5. InsertPos->next = InsertPoint;//前驱结点的后继指针指向插入结点
  6. DL->Length++;
  7. }

 

 

 6.按位删除数据元素

  1. bool DelList(DLinkList DL,DNode *DelPos,DNode *DelPoint){//删除数据元素(输入:双链表,删除结点的前驱结点)
  2. DelPos->next = DelPoint->next;//将前驱结点的后继指针指向删除结点的后继指针
  3. DelPoint->next->prior = DelPos;//将删除结点的后继结点的前驱指针指向删除结点的前驱结点
  4. free(DelPoint);//释放删除结点的存储空间
  5. DL->Length--;//长度-1
  6. }

 

三.整体代码

  1. //使用头插法实现双链表
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. typedef struct DNode{//定义双链表结点类型
  5. int Length;//长度
  6. int data;//数据域
  7. struct DNode *prior,*next;//前驱指针和后继指针
  8. }DNode,*DLinkList;
  9. DLinkList BulidList(DLinkList DL){//使用头插法创建双链表
  10. DL = (DLinkList)malloc(sizeof(DNode));//分配一个头结点
  11. if(DL==NULL){//分配失败
  12. return false;
  13. }
  14. DL->Length=0;//初始化
  15. DL->data = 0;
  16. DL->next = NULL;
  17. DL->prior = NULL;
  18. int addNum;//定义添值变量
  19. printf("向链表输入初始值\n");
  20. printf("请输入要插入的内容:");
  21. scanf("%d",&addNum);//获取插入内容
  22. while(addNum!=99){
  23. DNode *addPoint; //创建一个指针
  24. addPoint = (DNode *)malloc(sizeof(DNode));//指向创建的新结点
  25. addPoint->data = addNum;//赋值
  26. addPoint->next = DL->next;//头插法
  27. addPoint->prior = DL;
  28. DL->next = addPoint;
  29. DL->Length++;
  30. printf("请再次输入要插入的内容:");
  31. scanf("%d",&addNum);//获取插入内容
  32. }
  33. return DL;
  34. }
  35. void ShowList(DLinkList DL){
  36. DNode *x;//定义一个指针
  37. int num = DL->Length;//num用于暂存该链表长度
  38. printf("该链表一共有%d个元素\n",num);
  39. // x = (LNode *)malloc(sizeof(LNode));
  40. x = DL;//将头结点的信息赋给x
  41. x = x->next;//跳过头结点,因为头结点不存储数据
  42. while(num>0){
  43. printf("%d\n",x->data);//输出该节点的数据
  44. x = x->next;//移向下一个结点
  45. num--;//遍历总数减一
  46. }
  47. }
  48. DLinkList GetElem(DLinkList DL,int findPos){//按位查找
  49. DNode *record;//定义一个遍历指针
  50. record = DL;//遍历指针指向双链表表头
  51. int x = 1;//记录位置变量赋初值1
  52. while(record!=NULL){//当双链表没有遍历结束时
  53. record = record->next;//指针指向下一个结点
  54. if(x==findPos){//当查找位置和当前位置一致时
  55. printf("%d值在链表的第%d结点",record->data,x);//输出结果
  56. return record;//返回要查找的结点
  57. }
  58. x++;//累加
  59. }
  60. printf("没有找到");
  61. return NULL;//没找到返回空
  62. }
  63. bool InsertList(DLinkList DL,DNode *InsertPos,DNode *InsertPoint){//插入元素,输入:双链表,前驱结点,插入结点
  64. InsertPoint->next = InsertPos->next;//插入结点的后继指针指向前驱结点的后继结点
  65. InsertPos->next->prior=InsertPoint;//前驱结点原后继结点的前驱指针指向插入结点
  66. InsertPoint->prior = InsertPos;// 插入结点的前驱指针指向前驱结点
  67. InsertPos->next = InsertPoint;//前驱结点的后继指针指向插入结点
  68. DL->Length++;
  69. }
  70. bool DelList(DLinkList DL,DNode *DelPos,DNode *DelPoint){//删除数据元素(输入:双链表,删除结点的前驱结点)
  71. DelPos->next = DelPoint->next;//将前驱结点的后继指针指向删除结点的后继指针
  72. DelPoint->next->prior = DelPos;//将删除结点的后继结点的前驱指针指向删除结点的前驱结点
  73. free(DelPoint);//释放删除结点的存储空间
  74. DL->Length--;//长度-1
  75. }
  76. int main(){
  77. DLinkList DL;
  78. DL = BulidList(DL);//建立双链表
  79. ShowList(DL);
  80. //按位查找部分
  81. int findPos=0;//定义要寻找的位置
  82. DNode *getPos;//寻找的结点
  83. printf("\n请输入要寻找结点的位置:");
  84. scanf("%d",&findPos); //获取位置
  85. getPos = GetElem(DL,findPos);//按位查找
  86. //插入元素部分(按位插入)
  87. DNode *InsertPos;//定义前驱结点 指针
  88. DNode *InsertPoint;// 定义插入结点 指针
  89. int insertNum = 0;//定义插入值
  90. printf("\n请输入要插入结点的位置:");
  91. scanf("%d",&findPos); //获取插入位置
  92. InsertPos = GetElem(DL,findPos-1);//按位查找,找到前驱结点
  93. printf("\n请输入插入结点的值:");
  94. scanf("%d",&insertNum); //获取值
  95. InsertPoint = (DNode *)malloc(sizeof(DNode));//创建插入结点
  96. InsertPoint->data = insertNum;//给插入结点赋值
  97. InsertList(DL,InsertPos,InsertPoint);//进行插入操作(输入前驱结点和插入结点)
  98. ShowList(DL);
  99. //删除操作(按位删除)
  100. int findDelPos = 0;
  101. DNode *DelPos,*DelPoint;//定义删除结点的前驱结点指针
  102. printf("\n请输入要删除结点的位置:");
  103. scanf("%d",&findDelPos); //获取删除位置
  104. DelPos = GetElem(DL,findDelPos-1);//按位查找,找到前驱结点
  105. DelPoint = DelPos->next;//获得要删除的结点
  106. DelList(DL,DelPos,DelPoint);//删除操作
  107. ShowList(DL);
  108. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/456444
推荐阅读
相关标签
  

闽ICP备14008679号