判断一个单向链表是否有环,算法证明

判断一个单向链表是否有环:

给定链表的头指针:list *head。

步长法:
int looplist(list *head)
{
    list *p ,*q;
    if (head == NULL) {
        return 0;
    }
    p = head;
    q = head;
    while ((p->next != NULL) && (q->next != NULL) &&(q->next->next != NULL)) {
        p = p->next;
        q = q->next->next;
        if (p == q) {
            return 1;
        }
    }
    return 0;
    
}

证明步长法的正确性:
 

如果链表有环,不妨假设其环长度为M(>=2)。

p指针首次到达交点(N0)时,q指针已经进入环。

设p=0;q=q-p;

再进过i(i>=0)步后,p=(p+i)%m;q=(q+2*i)%m;

则必存在一个i使得(p+i)%m = (q+2*i)%m。(p,q 都为常数)。

延伸:

给你一个单向链表的头指针,可能最后不是NULL终止,而是循环链表。怎么找出这个链表循环部分的第一个节点。

解决思路: 

加入一个数组记录
p指针移动痕迹,第一次重复处即是第一个循环节点。

posted on 2008-04-21 21:34  清水无鱼  阅读(4022)  评论(1)    收藏  举报

导航