首页 > 其他 > 详细

如何判断单链表是否存在环

时间:2014-03-20 23:51:06      阅读:720      评论:0      收藏:0      [点我收藏+]

给定一个单链表,只给出头指针h:

1、如何判断是否存在环?

2、如何知道环的长度?

3、如何找出环的连接点在哪里?

4、带环链表的长度是多少?

解法:

1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。

2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰撞所走过的操作数就是环的长度s。

3、问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。

该定理的证明可参考:http://fayaa.com/tiku/view/7/

4、问题3中已经求出连接点距离头指针的长度,加上问题2中求出的环的长度,二者之和就是带环单链表的长度

 

判断是否存在环的程序:

bubuko.com,布布扣
bool IsExitsLoop(slist *head)
{
    slist *slow = head, *fast = head;

    while ( fast && fast->next ) 
    {
        slow = slow->next;
        fast = fast->next->next;
        if ( slow == fast ) break;
    }

    return !(fast == NULL || fast->next == NULL);
}
bubuko.com,布布扣

寻找环连接点(入口点)的程序:

bubuko.com,布布扣
slist* FindLoopPort(slist *head)
{
    slist *slow = head, *fast = head;

    while ( fast && fast->next ) 
    {
        slow = slow->next;
        fast = fast->next->next;
        if ( slow == fast ) break;
    }

    if (fast == NULL || fast->next == NULL)
        return NULL;

    slow = head;
    while (slow != fast)
    {
         slow = slow->next;
         fast = fast->next;
    }

    return slow;
}
bubuko.com,布布扣

以下是我(theCambrian)自己在上述基础上写的两个函数,如有误,请小伙伴们批评指正:

ps:今天去某公司面试的时候问道这个题,自己回答的不是很全面,特此总结。

计算环的长度:

bubuko.com,布布扣
int LoopLength(slist *crossPoint)
{
    if ( crossPoint == NULL )
        return -1; //-1 表示无环!
slist
*slow = crossPoint;
if ( slow->next == slow ) return 1; if (slow->next->next == slow) return 2; slow = crossPoint->next; slist *fast = crossPoint->next->next; size_t loopLen = 1; while ( fast != slow ) { fast = fast->next->next; slow = slow->next; ++loopLen; } return loopLen; }
bubuko.com,布布扣

计算链表总长度:

bubuko.com,布布扣
int sumLinkLength(slist *crossPoint)
{
    if ( crossPoint == NULL )
        return -1;

    slist * pHead = head;
    slist * pCrossPoint = crossPoint;

    size_t cnt = 0;
    while ( pHead != pCrossPoint )
    {
        pCrossPoint = pCrossPoint->next;
        pHead = pHead->next;
        ++cnt;
    }
    return ( LoopLength(crossPoint) + cnt );
}
bubuko.com,布布扣

上半部分原文链接:http://blog.csdn.net/liuxialong/article/details/6555850

如何判断单链表是否存在环,布布扣,bubuko.com

如何判断单链表是否存在环

原文:http://www.cnblogs.com/theCambrian/p/3614901.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!