数据结构 - 如何找到有环单链表的环的入口位置(C++)

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程

/*
 * Created by Chimomo.
 *
 * 解法如下:
 *
 * 设定fast和slow两个指针,初始都指向head。
 * 然后让fast每次走2步,slow每次走一步,如果发现fast和slow重合,则确定单向链表有环路了。
 * 接下来,让fast回到链表的头部,重新走,每次步长不是走2步了,而是走1步,那么当fast和slow再次相遇的结点,就是环路的入口位置了。
 *
 * 证明:
 *
 * 当fast和slow第一次相遇的时候,slow肯定没有遍历完一次链表或刚好遍历完一次链表,而fast已经在环内循环了n圈(n>=1)。
 * 这时,假设slow走了i个结点,则fast走了2i个结点,再假设环长为C,则
 *
 * 2i = i + nC -> i = nC
 *
 * 设链表长度为L,链表起点距环入口的距离为j,环入口距相遇点的距离为k,则
 *
 * j + k = i = nC
 *
 * j + k = (n - 1)C + C = (n - 1)C + (L - j)
 *
 * j = (n - 1)C + (L - j - k)
 *
 * (L - j - k)同k一样,同样为环入口点距相遇点的距离。
 * 也就是说,从链表起点到环入口点的距离等于(n - 1)环长+相遇点到入口点的距离。
 * 于是,从链表起点、相遇点分别设一指针,每次各走一步,则两指针必定相遇,且第一个相遇点即为环入口点。
 */

#include "SingleLinkedList.h"

/**
 * Get the loop entrance of single linked list.
 * @tparam T The type parameter.
 * @return The loop entrance of single linked list.
 */
template<class T>
Node<T> *SingleLinkedList<T>::getLoopEntrance() {
    Node<T> *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;
    }
    fast = head;
    while (slow != fast) {
        slow = slow->next;
        fast = fast->next;
    }
    return fast;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值