快慢指針判斷鏈表是否有環
原來的代碼判斷是否有環比較的是快慢指針是否有朝一日指向的節點的值相同,
而這是有漏洞的,當輸入的節點值有重復時,也可能使代碼作出有環的誤判,現修改其判斷指標為當兩個指針的地址相同時,則有環。
然而快慢指針缺點略大,兩指針極易錯過,當環巨大時,耗費過多的時間,也許存在優化的可能,改天再寫吧。。。
int hasloop(linklist l)//快慢指針判斷是否有環
{
node *p1,*p2;
if(l == NULL || l->next == NULL) //鏈表為空,或是單結點鏈表直接返回頭結點
return 0;
p1 = p2 = l;
while(p2->next != NULL && p1->next->next != NULL)
{
p1 = p1->next->next;
p2 = p2->next;
if(p1->data == p2->data)
return 1;
}
return 0;
}
修改後整題代碼如下:
實例:建立一個鏈表,判斷是否存在環
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
typedef struct node
{
char data;
struct node *next;
}node, *linklist;
void initlist(linklist *l)
{
*l = (linklist)malloc(sizeof(node));
(*l)->next=NULL;
}
void creatfromhead(linklist l)
{
node *s;
char c;
int flag = 1;
while(flag)
{
c = getchar();
if(c != ‘#‘)
{
s=(node*)malloc(sizeof(node));
s->data=c;
s->next = l->next;
l->next = s;
}
else
flag=0;
}
}
int hasLoop(linklist l)//快慢指針判斷是否有環
{
node *p1,*p2;
if(l == NULL || l->next == NULL) //鏈表為空,或是單結點鏈表直接返回頭結點
return 0;
p1 = p2 = l;
while(p2->next != NULL && p1->next->next != NULL)
{
p1 = p1->next->next;
p2 = p2->next;
if(p1== p2)
return 1;
}
return 0;
}
int main(int argc, char* argv[])
{
linklist l;
initlist(&l);
creatfromhead(l);
if(hasLoop(l))
printf("有環\n");
else
printf("無環\n");
return 0;
}
快慢指針判斷鏈表是否有環