当前位置:   article > 正文

使用C语言实现双向链表(带头结点)_带头结点双向链表c语言

带头结点双向链表c语言

目录

1.双链表

2.双链表的相关操作

(1)数据结构的定义

(2)初始化和销毁

(3)判断空和表的长度

(4)节点的后插操作

(5)按序查找第i个节点和按值查找节点

(6)定位删除和按序删除

(7)打印操作

(8)主函数

(9)测试


1.双链表

相对于单链表来说就是多一个前驱的指针prior,指向前一个节点(主要是为了方便删除和插入)。

注:由于之前的实现的单链表总是会遇到一种情况就是,如果要删除当前的节点p的话,那么只能通过一种技巧的方式计算交换值;但是如果是需要进行更加复杂的操作的话,就会比较麻烦,可能还需要辅助的指针r来指向当前节点的前驱,这会给程序写起来和理解起来带来不便,所以为了实现当前节点能够访问前驱节点,那么提出了双链表的概念。

使用C语言实现单链表(带头结点)

使用C语言实现单链表(不带头结点)

2.双链表的相关操作

(1)数据结构的定义

  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #define MAXSIZE 10
  4. typedef int ElemType;
  5. typedef struct DNode {
  6. ElemType data;
  7. struct DNode*prior,*next;
  8. }DNode,*DLinkList;
  9. //清单列表
  10. void MenuLinkList(){
  11. printf("-------------1.插入操作-------------\n");
  12. printf("-------------2.定位插入操作---------\n");
  13. printf("-------------3.按序查找操作---------\n");
  14. printf("-------------4.按值查找操作---------\n");
  15. printf("-------------5.定位删除操作---------\n");
  16. printf("-------------6.按值删除元素---------\n");
  17. printf("-------------7.删除整个表元素节点---\n");
  18. printf("-------------8.表的长度-------------\n");
  19. printf("-------------9.打印操作-------------\n");
  20. printf("-------------10.结束操作-------------\n");
  21. }

(2)初始化和销毁

  1. //初始化操作
  2. void InitDLinkList(DLinkList&L){
  3. L=(DNode*)malloc(sizeof(DNode));
  4. if(L==NULL){
  5. printf("申请空间失败!\n");
  6. return ;
  7. }
  8. L->prior=NULL;
  9. L->next=NULL;
  10. printf("申请空间成功!\n");
  11. }
  12. //销毁表(头节点不销毁)
  13. DNode* DestryDLinkList(DNode*p,DLinkList&L,int flag=9){
  14. //从尾部开始删除节点
  15. DNode*r=p;
  16. while(r!=L){
  17. DNode*s=r;
  18. r=r->prior;
  19. r->next=s->next;
  20. free(s);
  21. }
  22. //如果是结束操作的话,直接将头节点释放
  23. if(flag==10){
  24. free(L);
  25. L=NULL;
  26. }
  27. return r;
  28. }

这里的销毁操作主要是从最后节点开始进行删除,更加的方便,如果从头结点开始删除的话,需要判断的条件更多,相对麻烦一点,所以采用这种方法。读者自己可以实现从前往后的删除操作。

(3)判断空和表的长度

  1. //判空
  2. bool Empty(DLinkList L){
  3. if(L->next==NULL){
  4. return true;
  5. }else{
  6. return false;
  7. }
  8. }
  9. //表的长度
  10. int DLinkListLength(DLinkList L){
  11. int len=0;
  12. DNode*p=L->next;
  13. while(p!=NULL){
  14. len++;
  15. p=p->next;
  16. }
  17. return len;
  18. }

(4)节点的后插操作

  1. //节点的插入操作(后插)
  2. DNode* InsertDLinkList(DNode*p,ElemType e){
  3. if(p==NULL){
  4. printf("插入的节点不合法!\n");
  5. return NULL;
  6. }
  7. DNode*s=(DNode*)malloc(sizeof(DNode));
  8. s->data=e;
  9. s->next=p->next;
  10. p->next=s;
  11. s->prior=p;
  12. printf("插入节点成功!\n");
  13. return s;
  14. }
  15. //在第i个位置插入节点
  16. void InsertIDLinkList(DLinkList&L,int i,ElemType e){
  17. DNode*p=FindDNode(L,i);
  18. //如果是插入到尾节点
  19. if(p->next==NULL){
  20. InsertDLinkList(p,e);
  21. return ;
  22. }
  23. //插入到中间的节点
  24. if(p!=NULL){
  25. DNode*s=(DNode*)malloc(sizeof(DNode));
  26. s->data=e;
  27. s->next=p->next;
  28. p->next->prior=s;
  29. p->next=s;
  30. s->prior=p;
  31. printf("插入节点成功!\n");
  32. return ;
  33. }
  34. }

(5)按序查找第i个节点和按值查找节点

  1. //查找第i个位序的节点
  2. DNode*FindDNode(DLinkList L,int i){
  3. if(L==NULL){
  4. printf("表为空!\n");
  5. return NULL;
  6. }
  7. if(i<0||i>DLinkListLength(L)){
  8. printf("查找的位置不正确!\n");
  9. return NULL;
  10. }
  11. int j=1;
  12. DNode*p=L->next;
  13. while(p!=NULL&&j<i){
  14. p=p->next;
  15. j++;
  16. }
  17. return p;
  18. }
  19. //按值查找操作
  20. DNode*FindDElem(DLinkList L,ElemType e){
  21. if(L==NULL){
  22. printf("表为空!\n");
  23. return NULL;
  24. }
  25. DNode*p=L->next;
  26. while(p->data!=e){
  27. p=p->next;
  28. }
  29. return p;
  30. }

(6)定位删除和按序删除

  1. //定位删除节点
  2. void DeleteDLNode(DLinkList&L,int i,ElemType&e){
  3. DNode*p=FindDNode(L,i);
  4. e=p->data;
  5. //如果是尾节点直接删除
  6. if(p->next==NULL){
  7. p->prior->next=p->next;
  8. free(p);
  9. return ;
  10. }
  11. if(p!=NULL){
  12. DNode*s=p;
  13. p->prior->next=s->next;
  14. p->next->prior=s->prior;
  15. free(s);
  16. return ;
  17. }
  18. }
  19. //按值删除
  20. void DeleteDElem(DLinkList&L,ElemType e){
  21. DNode*p=FindDElem(L,e);
  22. //如果是尾节点直接删除
  23. if(p->next==NULL){
  24. p->prior->next=p->next;
  25. free(p);
  26. return ;
  27. }
  28. if(p!=NULL){
  29. DNode*s=p;
  30. p->prior->next=s->next;
  31. p->next->prior=s->prior;
  32. free(s);
  33. return ;
  34. }
  35. }

(7)打印操作

  1. //打印
  2. void PrintDLinkList(DLinkList L){
  3. DNode*p=L->next;
  4. while(p!=NULL){
  5. printf("%d\t",p->data);
  6. p=p->next;
  7. }
  8. printf("\n");
  9. }

(8)主函数

  1. int main(){
  2. DLinkList L;
  3. InitDLinkList(L);
  4. //对顺序表进行插入操作
  5. ElemType x;
  6. int flag=-1;
  7. DNode*p=L;
  8. //各种操作
  9. while(1) {
  10. int i=0;
  11. ElemType e=0;
  12. MenuLinkList();
  13. printf("请输入操作: ");
  14. scanf("%d",&flag);
  15. int len=0;
  16. DNode*s;
  17. switch(flag){
  18. case 1:
  19. printf("请输入元素(-1_end): ");
  20. scanf("%d",&x);
  21. while(x!=-1) {
  22. p=InsertDLinkList(p,x);
  23. printf("请输入元素(-1_end): ");
  24. scanf("%d",&x);
  25. }
  26. break;
  27. case 2:
  28. printf("请输入元素插入位置: \n");
  29. scanf("%d",&i);
  30. printf("请输入元素: ");
  31. scanf("%d",&x);
  32. InsertIDLinkList(L,i,x);
  33. break;
  34. case 3:
  35. printf("请输入查找元素位置: ");
  36. scanf("%d",&i);
  37. s=FindDNode(L,i);
  38. if(s!=NULL){
  39. printf("查找的元素为 = %d\n",s->data);
  40. }
  41. break;
  42. case 4:
  43. printf("请输入要查找的值: ");
  44. scanf("%d",&x);
  45. s=FindDElem(L,x);
  46. if(s!=NULL){
  47. printf("查找的元素存在!\n");
  48. }else{
  49. printf("查找的元素不存在!\n");
  50. }
  51. break;
  52. case 5:
  53. printf("请输入删除的定位位置: ");
  54. scanf("%d",&i);
  55. DeleteDLNode(L,i,e);
  56. printf("删除的元素为 = %d\n",e);
  57. break;
  58. case 6:
  59. printf("请输入要删除的元素: ");
  60. scanf("%d",&e);
  61. DeleteDElem(L,e);
  62. break;
  63. case 7:
  64. p=DestryDLinkList(p,L);
  65. printf("删除成功!\n");
  66. break;
  67. case 8:
  68. len=DLinkListLength(L);
  69. printf("表的长度 = %d\n",len);
  70. break;
  71. case 9:
  72. PrintDLinkList(L);
  73. break;
  74. default:
  75. DestryDLinkList(p,L,flag);
  76. printf("结束操作\n");
  77. }
  78. if(flag==10){
  79. break;
  80. }
  81. }
  82. return 0;
  83. }

(9)测试

 

 

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

闽ICP备14008679号