当前位置:   article > 正文

【链表】判断链表是否有环-快慢指针_判断链表是否存在环快慢指针

判断链表是否存在环快慢指针

目录

一、思想

二、代码

三、运行结果


一、思想

什么叫有环?

        一个结点有两个指向的时候就会产生环。例如在一个单链表0-9的数据中,3的下个节点为4,让3的下个结点同时指向9,此时就会在3的位置产生两条路,一个指向9,一个指向4,这就是有环的情况。

快慢指针求解:

  • 慢指针一次走一次
  • 快指针一次走两次
  • 如果有环,快指针会在环里转圈圈,慢指针也会在某时刻进入环内,两指针相遇。;没有环,快指针会优先走到空NULL。
  • 如果有环-->快慢指针迟早会相遇

空不能作为循环条件,如果有环,快慢指针会在环内,永远不会到达空的位置,会陷入死循环。

二、代码

  1. #include <assert.h>
  2. #include<stdio.h>
  3. typedef struct Node
  4. {
  5. int data;
  6. struct Node* next;
  7. }Node, * List;
  8. //初始化
  9. void InitList(List plist)
  10. {
  11. assert(plist != NULL);
  12. if (plist == NULL)
  13. {
  14. return;
  15. }
  16. //plist->data;//头节点的data不使用
  17. plist->next = NULL;
  18. }
  19. //尾插
  20. bool Insert_tail(List plist, int val)
  21. {
  22. assert(plist != NULL);
  23. if (plist == NULL)
  24. {
  25. return false;
  26. }
  27. //申请结点
  28. Node* p = (Node*)malloc(sizeof(Node));
  29. assert(p != NULL);
  30. //将数据val放入到新结点;
  31. p->data = val;
  32. //找尾巴
  33. Node* q;
  34. for (q = plist; q->next != NULL; q = q->next)
  35. {
  36. ;
  37. }
  38. //插入新结点,把p插入到q的后面
  39. p->next = q->next;//p->next=NULL;
  40. q->next = p;
  41. return true;
  42. }
  43. //在plist查找第一个key值,找到返回结点地址,没有找到返回NULL;
  44. Node* Search(List plist, int key)
  45. {
  46. assert(plist != NULL);
  47. if (plist == NULL)
  48. {
  49. return NULL;
  50. }
  51. for (Node* p = plist->next; p != NULL; p = p->next)
  52. {
  53. if (p->data == key)
  54. {
  55. return p;
  56. }
  57. }
  58. return NULL;
  59. }
  60. bool IsCircle(List plist)
  61. {
  62. assert(plist != NULL);
  63. if (plist == NULL ||plist->next==NULL)
  64. {
  65. return false;
  66. }
  67. Node* p = plist->next;//慢指针,一次走一步
  68. Node* q = plist->next->next;//快指针,一次走两步;
  69. while (q != NULL && q->next!=NULL)
  70. {
  71. if (p == q)
  72. {
  73. break;
  74. }
  75. p = p->next;
  76. q = q->next->next;
  77. }
  78. if (q == NULL || q->next == NULL)
  79. {
  80. return false;
  81. }
  82. else
  83. {
  84. return true;
  85. }
  86. }
  87. //输出
  88. void Show(List plist)
  89. {
  90. assert(plist != NULL);
  91. if (plist == NULL)
  92. {
  93. return;
  94. }
  95. for (Node* p = plist->next; p != NULL; p = p->next)
  96. {
  97. printf("%d ", p->data);
  98. }
  99. printf("\n");
  100. }
  101. int main()
  102. {
  103. Node head;
  104. InitList(&head);
  105. //测试数据一:无环情况
  106. for (int i = 0; i < 10; i++)
  107. {
  108. Insert_tail(&head, i);
  109. }
  110. Show(&head);
  111. if (IsCircle(&head))
  112. {
  113. printf("该链表有环!\n");
  114. }
  115. else
  116. {
  117. printf("该链表没有环!\n");
  118. }
  119. //测试数据二:让3的下个结点指向9=》有环情况
  120. Node* q = Search(&head, 3);
  121. Node* s = Search(&head, 9);
  122. s->next = q;//构造环
  123. if (IsCircle(&head))
  124. {
  125. printf("该链表有环!\n");
  126. }
  127. else
  128. {
  129. printf("该链表没有环!\n");
  130. }
  131. return 0;
  132. }

三、运行结果

0-9的第一批数据:无环

让3的下个结点指向9,构造有环的第二批数据:有环

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号