📜  用于检测链表中循环的 C 程序

📅  最后修改于: 2022-05-13 01:54:24.969000             🧑  作者: Mango

用于检测链表中循环的 C 程序

给定一个链表,检查链表是否有循环。下图显示了一个带有循环的链表。

解决方案:弗洛伊德的寻环算法
方法:这是最快的方法,如下所述:

  • 使用两个指针遍历链表。
  • 将一个指针(slow_p)移动一格,将另一指针(fast_p)移动两格。
  • 如果这些指针在同一个节点相遇,则存在一个循环。如果指针不满足,则链表没有循环。

下图显示了 detectloop函数在代码中的工作方式:

Floyd 寻环算法的实现:

C
// C program to detect loop in a linked list
#include 
#include 
  
/* Link list node */
struct Node {
    int data;
    struct Node* next;
};
  
void push(struct Node** head_ref, int new_data)
{
    /* allocate node */
    struct Node* new_node
        = (struct Node*)malloc(sizeof(struct Node));
  
    /* put in the data  */
    new_node->data = new_data;
  
    /* link the old list off the new node */
    new_node->next = (*head_ref);
  
    /* move the head to point to the new node */
    (*head_ref) = new_node;
}
  
int detectLoop(struct Node* list)
{
    struct Node *slow_p = list, *fast_p = list;
  
    while (slow_p && fast_p && fast_p->next) {
        slow_p = slow_p->next;
        fast_p = fast_p->next->next;
        if (slow_p == fast_p) {
            return 1;
        }
    }
    return 0;
}
  
/* Driver program to test above function*/
int main()
{
    /* Start with the empty list */
    struct Node* head = NULL;
  
    push(&head, 20);
    push(&head, 4);
    push(&head, 15);
    push(&head, 10);
  
    /* Create a loop for testing */
    head->next->next->next->next = head;
  
    if (detectLoop(head))
        printf("Loop found");
    else
        printf("No Loop");
    return 0;
}


输出
Loop found

复杂性分析:

  • 时间复杂度: O(n)。
    只需要遍历一次循环。
  • 辅助空间: O(1)。
    不需要空间。

上述算法如何工作?
请参阅:弗洛伊德的慢速和快速指针方法如何工作?
https://www.youtube.com/watch?v=Aup0kOWoMVg

有关详细信息,请参阅链接列表中有关检测循环的完整文章!