判断单链表是否有环
1.判断是否有环: 两个指针分别从起点开始遍历,fast每次一步,slow每次两步,若两个指针有相遇的时候,则表示有环,因为如果存在环,快的指针肯定会在环中与慢的指针相遇,就像分针和秒针一样 .
2.找出环的起点:在1的基础上,从两个指针相遇的点处,每次一步移动一个指针,直到指针转了一圈回来,这样就可以知道环的大小C。之后,两个指针从链表起点出发,每次一步,让其中一个指针先走C步,则两个指针相遇的点就是环的起点。
以下是代码,因为只是说明这个问题,所以故意写了一个循环链表。
#include<stdio.h>
#include<malloc.h>
typedef struct _NODE
{
int data;
struct _NODE* next;
}NODE;
struct _NODE* p;
struct _NODE* q;
struct _NODE* InsertLinkList(int e, struct _NODE* head)
{
struct _NODE* s;
s = (NODE*)malloc(sizeof(NODE));
if (head == NULL)
{
s->data = e;
head= s;
s->next = NULL;
p = s;
return head;
}
s->data=e;
s->next = head;
head = s;
if (e ==8 )
{
p->next = s;
}
return head;
}
//寻找起始位置
void FindNode(struct _NODE* head)
{
struct _NODE* fast=head;
struct _NODE* slow=head;
slow = slow->next;
fast = fast->next->next;
//从这个循环出来,说明有环
while (fast->data != slow->data)
{
slow = slow->next;
fast = fast->next->next;
}
fast = head;
//从这个循环出来,说明找到了起始位置
while (fast->data != slow->data)
{
slow = slow->next;
fast = fast->next;
}
printf("%d ", fast->data);
}
//输出链表
void Show(struct _NODE* head)
{
struct _NODE* pos;
pos = (NODE*)malloc(sizeof(NODE));
pos = head;
while (pos)
{
printf("%d ", pos->data);
pos=pos->next;
}
}
int main()
{
struct _NODE* head;
head = NULL;
head = InsertLinkList(1, head);
head = InsertLinkList(2, head);
head = InsertLinkList(3, head);
head = InsertLinkList(4, head);
head = InsertLinkList(5, head);
head = InsertLinkList(6, head);
head = InsertLinkList(7, head);
head = InsertLinkList(8, head);
head = InsertLinkList(9, head);
head = InsertLinkList(10, head);
head = InsertLinkList(11, head);
head = InsertLinkList(12, head);
head = InsertLinkList(13, head);
head = InsertLinkList(14, head);
head = InsertLinkList(15, head);
//Show(head);
FindNode(head);
return 0;
}