用于检测链表中循环的 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
有关详细信息,请参阅链接列表中有关检测循环的完整文章!