单链表成环的相关问题

链表结构:

typedef struct ListNode{
    int val;
    struct ListNode *next;
}ListNode;

1.判断一个单链表是否有环

这个问题采用追击的方法,定义两个指针,一个一次走两步,一个一次走一步,如果相遇了就说明有环。

int is_cycle(LinkList *list){
    if(list==NULL || list->next==NULL)return -1;
    LinkList *fast=list;
    LinkList *slow=list;
    while(fast!=NULL && fast->next!=NULL){
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)return 0;
    }
    return -1;
}

2.判断有环单链表环的起始位置

有个定理,第一问中两个指针相遇点到环起始位置的距离与从链表头到环起始位置的距离是相等的。这样就不难找到环开始的节点了。

LinkList *begin_cycle(LinkList *head){
    if(head==NULL || head->next==NULL)return NULL;
    LinkList *fast=head;
    LinkList *slow=head;
    while(fast!=NULL && fast->next!=NULL){
        fast=fast->next->next;
        slow=slow->next;
        if(slow==fast)break;
    }
    if(fast==NULL || fast->next==NULL)return NULL;//判断一下是否有环,没有就返回NULL。(如果明确说是带环的,这个不要也可以)
    slow=head;
    while(slow!=fast){
        slow=slow->next;
        fast=fast->next;
    }
    return fast;
}

除去以上两个问题,还有一个是求环的长度和链表的长度,这两个问题应该很简单,从相遇点开始,一个指针绕圈另一个等待,再次相遇时走过的路径就是一个整圈的环。有了环的长度,再加上可以找到环开始的点,那么也就不难找到链表的长度了吧。(再加上从表头到开始点的长度)

posted on 2014-09-10 13:40  高山漏水  阅读(1395)  评论(0编辑  收藏  举报