【面试题】-判断单链表是否有环并找到环入口(快慢指针)

快慢指针

所谓的快慢指针的快慢是指指针向前移动的步长。比如在单链表中,快指针每次向前移动2个步长,慢指针则每次向前移动1个步长。

单链表环

单链表有环的定义是链表的尾节点指向了链表中间的某个结点。比如下图。(图片来自http://www.nowamagic.net/librarys/veda/detail/2245

这里写图片描述

解题思路

判断单链表是否有环同样利用快慢指针的原理, 设置快慢指针 *fast 、 *slow 都指向单链表的头节点, 其中 *fast 的移动速度是 *slow 的2倍。如果是有环的链表的话,快指针始终都会追上慢指针。即在循环的过程中判断两指针是否会相等,如果相等,则是。

如果判断出单链表有环,如何找到环的入口,比如上图中,D就是环的入口。假设慢指针移动了S个结点,则快指针移动了2S个结点,如果环入口离头结点为x,环入口离相遇的那个结点为y,环的长度为r,单链表总长度为L,他们的关系推导如下:

  • 2S = S + n * r (快指针的步数等于S 加上环上多转的n圈)
  • S = n * r
  • S = x + y = n * r
  • x + y = (n-1)*L + r
  • x + y = (n-1)*L + L - x
  • x = (n-1)*L + L - x - y

从最后一个式子知道,L - x - y为相遇点到环入口的距离,也就是说一个指针从头结点出发,另一个指针从相遇点出发,步长都为1的话,这两个指针一定会在环入口相遇。

代码实现

是否有环

int Is_ListLoop(LinkList L){
    LinkList fast, slow;
    if(L == NULL || L->next == NULL){
        exit(ERROR);
    }

    fast = slow = L;

    while(fast->next != NULL && fast->next->next != NULL){
        slow = slow->next;
        fast = fast->next->next;
        if(fast == slow){
            printf("the List is Loop\n");
            return TRUE;
        }
    }

    printf("the List is no Loop\n");
    return FALSE;

}

找到环入口

int Find_Loop(LinkList L){
    LinkList fast, slow;
    if(L == NULL || L->next<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值