怎样才能检测到链表中存在循环?

这是《C专家编程》里面的题目。书中给这个题目加了几个限制。

第三个限制:内存空间非常有限,无法创建一个足够长的数组。但是假定如果链表存在循环,它出现在前N个元素中。

题目分析:可以用两层循环来做。对每一个元素,搜索其后元素直到第N个。指针为Null代表没有环。

简单代码如下:

 1 struct List{  
 2     int data;  
 3     struct List *next;  
 4 };  
 5 bool HasCircle(struct List *head,int N)  
 6 {  
 7     struct List *cur1 = head;  //
 8     if(head->next != NULL)
 9         struct List *cur2 = head->next;  //
10     else
11         return false;
12     int postion1 = 0,postion2 = 1;
13     while(cur1){    
14           
15         if(postion1 > N)
16             return false;
17         while(cur2){  
18             
19             if(postion2 > N)
20                 break;
21             if(cur2 == cur1)
22                 return true; //has circle  
23             cur2 = cur2->next;  
24             postion2++;
25         }
26         cur1 = cur1->next;  
27         postion1++;
28     }  
29     return false;  
30 }  

 

第四个限制:链表的长度是任意的,而且循环可能出现在任何位置。

题目分析:根据书中说的,用一个快指针(每次走两步)一个慢指针(每次走一步),如果两个指针相遇,说明有环。

这个理论可以简单的证明一下:假如在某一时刻慢指针走到了环的位置,此时快指针肯定早已经在环里跑了好久了。这时如果快指针与慢指针相距M步的距离,因为快指针比慢指针每次多走一步,那么在M步之后,快指针将会和慢指针相遇。

 

转载于:https://www.cnblogs.com/aiqin/p/4331570.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值