Floyd 判圈算法是用于判断链表中有无环以及检测环入点的经典算法。
它利用了快慢指针的思想,以及环无终点,快慢指针互相追逐,相遇即环存在,再移动一个指针到头部,两指针再每次移动1结点,第二次相遇即得环起点。
在线玩:cycle.html
code
#include <stdlib.h>
#include <stdio.h>
typedef int elemType;
typedef struct nodeList
{
elemType data;
struct nodeList *next;
} nodeList, *NodeList;
nodeList *initCycle();
void freeNodeList(nodeList *a);
void Floyd()
{
nodeList *c = initCycle();
// 确定环存在
nodeList *slow = c->next;
nodeList *fast = c->next;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
{
printf("has cycle");
break;
}
}
if (!fast || !fast->next)
{
printf("no cycle");
return;
}
// 确定环起点
slow = c->next;
while (slow != fast)
{
fast = fast->next;
slow = slow->next;
}
printf("\ncycle start at %d", slow->data);
freeNodeList(c);
}
int main()
{
Floyd();
return 0;
}
void freeNodeList(nodeList *a)
{
// 确定环起点,断开环,再释放内存
}
nodeList *initCycle()
{
nodeList *c = (nodeList *)malloc(sizeof(nodeList));
c->next = NULL;
nodeList *enter;
nodeList *trail;
for (int i = 8; i >= 0; i--)
{
nodeList *p = (nodeList *)malloc(sizeof(nodeList));
p->data = i;
p->next = c->next;
c->next = p;
if (i == 8)
trail = p; // 尾部为null
if (i == 3)
enter = p;
}
trail->next = enter; // 闭合
return c;
}
output
❮cmd❯ …\pblog main [ ✓] via v22.22.2 via v3.14.5
の a
has cycle
cycle start at 3