怎样才能检测到链表中循环
2013-10-31 14:07
239 查看
《C专家编程》附录A.2
~~~~~~~~~~~~~~~~~~~~~~割了?~~~~~~~~~~~~~~~~~~
http://blog.chinaunix.net/uid-23629988-id-2191643.html
算法实现:使用快慢指针,检测单链表是否存在循环2011-08-15 21:02:31
分类: C/C++
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:gfree.wind@gmail.com
博客:linuxfocus.blog.chinaunix.net
今天的题目是检查单链表是否存在循环。对于初学者来说,要解决这个问题,最可能采取的方法就是使用两个循环。当外层循环步进一个节点时,内层循环就遍历外层循环节点之后的所有节点,然后比较内外循环的两个节点。若有节点地址相等,则表明该单链表有循环,反之则不存在循环。这种方法无疑效率比较低。
今天给大家介绍一个经典的方法,通过快慢指针来检查单链表是否存在循环。其思路很简单,大家可以想一下上体育课长跑的情景。当同学们绕着操场跑步的时候,速度快的同学会遥遥领先,最后甚至会超越其它同学一圈乃至n圈——这是绕圈跑。那么如果不是绕圈跑呢?速度快的同学则会一直领先直到终点,不会再次碰到后面的速度慢同学——不考虑地球是圆的这种情况O(∩_∩)O哈!
快慢指针的设计思想也是这样。快指针每次步进多个节点——这个视情况而定,慢指针每次只步进一个节点。那么如果该链表存在循环的话,快指针一定会再次碰到慢指针,反之则不存在循环。
下面上代码
struct list_node {
struct list_node *next;
void *data;
};
#define FALSE 0
#define TRUE 1
typedef unsigned char bool;
bool is_list_exist_loop(struct list_node
*head)
{
/*
快指针步进长度,之前我认为可以为其它值,但是从Bean_lee的回复中知道,不能为超过循环节点个数的值。
当超过循环节点个数时,而慢结点还未步入这个循环时,快节点会一直在循环中步进直至慢节点也步入这个循环。
*/
#define FAST_POINT_STEP 2
if (!head) returnFALSE;
struct list_node *fast,*slow;
unsigned int i;
/* 快慢指针都处于同一起跑线,即头指针位置 */
fast = slow = head;
while (fast){
/* 快指针步进 */
for (i= 0; i
< FAST_POINT_STEP;
++i)
{
fast = fast->next;
if (fast== slow){
/* 又碰到了慢指针,循环存在 */
return TRUE;
}
else if(!fast){
/* 快指针跑到头了,循环不存在 */
return FALSE;
}
}
/* 慢指针步进 */
slow = slow->next;
}
return FALSE;
}
仍然是抛砖引玉,大家还有什么经典的方法来解决这个问题呢?
~~~~~~~~~~~~~~~~~~~~~~割了?~~~~~~~~~~~~~~~~~~
http://blog.chinaunix.net/uid-23629988-id-2191643.html
算法实现:使用快慢指针,检测单链表是否存在循环2011-08-15 21:02:31
分类: C/C++
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:gfree.wind@gmail.com
博客:linuxfocus.blog.chinaunix.net
今天的题目是检查单链表是否存在循环。对于初学者来说,要解决这个问题,最可能采取的方法就是使用两个循环。当外层循环步进一个节点时,内层循环就遍历外层循环节点之后的所有节点,然后比较内外循环的两个节点。若有节点地址相等,则表明该单链表有循环,反之则不存在循环。这种方法无疑效率比较低。
今天给大家介绍一个经典的方法,通过快慢指针来检查单链表是否存在循环。其思路很简单,大家可以想一下上体育课长跑的情景。当同学们绕着操场跑步的时候,速度快的同学会遥遥领先,最后甚至会超越其它同学一圈乃至n圈——这是绕圈跑。那么如果不是绕圈跑呢?速度快的同学则会一直领先直到终点,不会再次碰到后面的速度慢同学——不考虑地球是圆的这种情况O(∩_∩)O哈!
快慢指针的设计思想也是这样。快指针每次步进多个节点——这个视情况而定,慢指针每次只步进一个节点。那么如果该链表存在循环的话,快指针一定会再次碰到慢指针,反之则不存在循环。
下面上代码
struct list_node {
struct list_node *next;
void *data;
};
#define FALSE 0
#define TRUE 1
typedef unsigned char bool;
bool is_list_exist_loop(struct list_node
*head)
{
/*
快指针步进长度,之前我认为可以为其它值,但是从Bean_lee的回复中知道,不能为超过循环节点个数的值。
当超过循环节点个数时,而慢结点还未步入这个循环时,快节点会一直在循环中步进直至慢节点也步入这个循环。
*/
#define FAST_POINT_STEP 2
if (!head) returnFALSE;
struct list_node *fast,*slow;
unsigned int i;
/* 快慢指针都处于同一起跑线,即头指针位置 */
fast = slow = head;
while (fast){
/* 快指针步进 */
for (i= 0; i
< FAST_POINT_STEP;
++i)
{
fast = fast->next;
if (fast== slow){
/* 又碰到了慢指针,循环存在 */
return TRUE;
}
else if(!fast){
/* 快指针跑到头了,循环不存在 */
return FALSE;
}
}
/* 慢指针步进 */
slow = slow->next;
}
return FALSE;
}
仍然是抛砖引玉,大家还有什么经典的方法来解决这个问题呢?
相关文章推荐
- 怎样才能检测到链表中存在循环
- 怎样检测链表中存在循环?
- 怎样检测链表中存在循环?
- 怎样检测链表中存在循环?
- C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- 怎样循环的创建链表
- c语言中while((c=getchar())!=EOF)怎样才能输入EOF是循环中断
- 怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- 怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- 转:C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- 检测链表中是否存在循环
- 双向循环链表-----C++
- 单向循环链表
- 一个建立双向循环链表的例子
- 如何判断一个单向链表是否存在循环的经典方法
- Linux_进程死锁?产生条件?产生原因?怎样预防?怎样检测死锁和解除死锁?
- 指针p,q,r依次指向某循环链表中三个相邻的结点,交换结点*q,*r在表中次序的程序段是
- 怎样才能娶到比尔-盖茨的女儿
- 双向循环链表——STL迭代器