当前位置:   article > 正文

双向链表的插入和删除的实现

双向链表的插入和删除

双向链表的操作实现包括:初始化指针,打印链表,插入链表以及删除链表。

1、初始化结构体

实现的代码如下:

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. //初始化结构体,一个是前驱指针,一个后继指针.
  4. typedef struct DoubleLinkedNode{
  5. char data;
  6. struct DoubleLinkedNode *previous;
  7. struct DoubleLinkedNode *next;
  8. } DLNode, *DLNodePtr;
  9. //初始化链表
  10. DLNodePtr initLinkList(){
  11. DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));//为dlnode申请一个大小为doublelinkednode指针大小的内存空间.
  12. tempHeader->data = '\0';
  13. tempHeader->previous = NULL;
  14. tempHeader->next = NULL;
  15. return tempHeader;
  16. }

2、打印链表

实现的代码如下:

  1. //打印链表函数
  2. void printList(DLNodePtr paraHeader){
  3. DLNodePtr p = paraHeader->next;
  4. while (p != NULL) {
  5. printf("%c", p->data);
  6. p = p->next;
  7. }
  8. printf("\r\n");
  9. }

3、实现插入

  1. //插入链表函数
  2. void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
  3. DLNodePtr p, q, r;
  4. // 第一步,查找位置,将指针p放到表头.
  5. p = paraHeader;
  6. for (int i = 0; i < paraPosition; i ++) {
  7. p = p->next;
  8. if (p == NULL) {
  9. printf("位置%d已经是最后一位了", paraPosition);
  10. return;
  11. }
  12. }
  13. //申请一块新的内存空间.
  14. q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
  15. q->data = paraChar;
  16. //开始插入新的链表.
  17. r = p->next;
  18. q->next = p->next;
  19. q->previous = p;
  20. p->next = q;
  21. if (r != NULL) {
  22. r->previous = q;
  23. }
  24. }

 实现的代码如上:

4、删除函数

代码:

  1. //删除链表函数.
  2. void deleteElement(DLNodePtr paraHeader, char paraChar){
  3. DLNodePtr p, q, r;
  4. p = paraHeader;
  5. //锁定目标,必须是删除链表的前一个结点.
  6. while ((p->next != NULL) && (p->next->data != paraChar)){
  7. p = p->next;
  8. }
  9. //报错检查
  10. if (p->next == NULL) {
  11. printf("'%c'字符不存在\n", paraChar);
  12. return;
  13. }
  14. //删除链表
  15. q = p->next;
  16. r = q->next;
  17. p->next = r;
  18. if (r != NULL) {
  19. r->previous = p;
  20. }
  21. // 释放空间.
  22. free(q);
  23. }

完整代码如下:

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. //初始化结构体,一个是前驱指针,一个后继指针.
  4. typedef struct DoubleLinkedNode{
  5. char data;
  6. struct DoubleLinkedNode *previous;
  7. struct DoubleLinkedNode *next;
  8. } DLNode, *DLNodePtr;
  9. //初始化链表
  10. DLNodePtr initLinkList(){
  11. DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));//为dlnode申请一个大小为doublelinkednode指针大小的内存空间.
  12. tempHeader->data = '\0';
  13. tempHeader->previous = NULL;
  14. tempHeader->next = NULL;
  15. return tempHeader;
  16. }
  17. //打印链表函数
  18. void printList(DLNodePtr paraHeader){
  19. DLNodePtr p = paraHeader->next;
  20. while (p != NULL) {
  21. printf("%c", p->data);
  22. p = p->next;
  23. }
  24. printf("\r\n");
  25. }
  26. //插入链表函数
  27. void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
  28. DLNodePtr p, q, r;
  29. // 第一步,查找位置,将指针p放到表头.
  30. p = paraHeader;
  31. for (int i = 0; i < paraPosition; i ++) {
  32. p = p->next;
  33. if (p == NULL) {
  34. printf("位置%d已经是最后一位了", paraPosition);
  35. return;
  36. }
  37. }
  38. //申请一块新的内存空间.
  39. q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
  40. q->data = paraChar;
  41. //开始插入新的链表.
  42. r = p->next;
  43. q->next = p->next;
  44. q->previous = p;
  45. p->next = q;
  46. if (r != NULL) {
  47. r->previous = q;
  48. }
  49. }
  50. //删除链表函数.
  51. void deleteElement(DLNodePtr paraHeader, char paraChar){
  52. DLNodePtr p, q, r;
  53. p = paraHeader;
  54. //锁定目标,必须是删除链表的前一个结点.
  55. while ((p->next != NULL) && (p->next->data != paraChar)){
  56. p = p->next;
  57. }
  58. //报错检查
  59. if (p->next == NULL) {
  60. printf("'%c'字符不存在\n", paraChar);
  61. return;
  62. }
  63. //删除链表
  64. q = p->next;
  65. r = q->next;
  66. p->next = r;
  67. if (r != NULL) {
  68. r->previous = p;
  69. }
  70. // 释放空间.
  71. free(q);
  72. }
  73. //插入删除测试函数
  74. void insertDeleteTest(){
  75. // 初始化一个空链表.
  76. DLNodePtr tempList = initLinkList();
  77. printList(tempList);
  78. //添加字符进行测试.
  79. insertElement(tempList, 'H', 0);
  80. insertElement(tempList, 'e', 1);
  81. insertElement(tempList, 'l', 2);
  82. insertElement(tempList, 'l', 3);
  83. insertElement(tempList, 'o', 4);
  84. insertElement(tempList, '!', 5);
  85. printList(tempList);
  86. //删除个别字符进行测试.
  87. deleteElement(tempList, 'e');
  88. deleteElement(tempList, 'a');
  89. deleteElement(tempList, 'o');
  90. printList(tempList);
  91. // 删除指定位置的字符.
  92. insertElement(tempList, 'o', 1);
  93. printList(tempList);
  94. }
  95. //设计打印存放字符地址的函数
  96. void basicAddressTest(){
  97. DLNode tempNode1, tempNode2;
  98. tempNode1.data = 4;
  99. tempNode1.next = NULL;
  100. tempNode2.data = 6;
  101. tempNode2.next = NULL;
  102. printf("第一个位置: %d, %d, %d\r\n",
  103. &tempNode1, &tempNode1.data, &tempNode1.next);
  104. printf("第二个位置: %d, %d, %d\r\n",
  105. &tempNode2, &tempNode2.data, &tempNode2.next);
  106. tempNode1.next = &tempNode2;
  107. }
  108. int main(){
  109. insertDeleteTest();
  110. basicAddressTest();
  111. }

运行结果:

总结:

双向链表是链表的一种,它和单向链表的区别是双向链表比单向链表每个节点多一个头指针,这个指针指向前一个节点,也就是说,每个节点包含包含头指针、存储元素、尾指针, 因此从这个节点可以同时访问到它前面和后面的节点。我们可以想一下,如果是单向链表,要访问一个节点前面的节点,就必须要从头结点开始遍历,直到找个这个节点前面的节点为止,而双向链表直接就可以访问前一个节点,查询和操作数据就会更加方便。这也是节省空间和时间的一种方式。

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

闽ICP备14008679号