信息发布→ 登录 注册 退出

c++中如何实现弗洛伊德判圈算法_c++判断链表是否有环

发布时间:2026-01-05

点击量:
弗洛伊德判圈算法核心是用slow(步长1)和fast(步长2)双指针遍历单链表,若相遇则有环,若fast遇nullptr则无环;C++实现需先判空和单节点,循环条件为fast&&fast->next,移动后立即比较指针是否相等。

弗洛伊德判圈算法的核心逻辑是什么

它不依赖额外空间,只用两个指针——slowfast,在单链表上同步移动:slow 每次走 1 步,fast 每次走 2 步。如果链表有环,二者必在环内相遇;若 fast 先走到 nullptr,说明无环。

如何用 C++ 实现基础判环(无环返回 false,有环返回 true)

注意边界:空链表或仅一个节点时,fast->next 可能非法,必须先检查 fastfast->next 是否为 nullptr

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

bool hasCycle(ListNode *head) {
    if (!head || !head->next) return false;

    ListNode *slow = head;
    ListNode *fast = head;

    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) return true;
    }
    return false;
}

为什么 fast 要走两步而不是三步或更多

走两步是效率与正确性平衡的结果:

  • fast 走 3 步,可能跳过 slow,导致一次循环内不相遇,需更多轮才能捕获,但不破坏正确性
  • 但走 2 步能保证:只要存在环,相对速度为 1,fast 必然在有限步内追上 slow(数学上可证最多绕环一圈就相遇)
  • 走 >2 步会增加空指针解引用风险(如 fast->next->next->next),且无性能收益

常见误写和崩溃点

最常出错的是循环条件和移动顺序:

  • 错误写法:while (fast->next && fast) —— 顺序反了,fastnullptr 时访问 fast->next 直接段错误
  • 错误写法:先移动再判断(如把 if (slow == fast) 放在移动之后但没处理初始重合)—— 若链表只有一个节点且自环(head->next == head),初始 slow == fast,但未进循环就被跳过
  • 正确做法:循环条件严格为 fast && fast->next,且每次移动后立即判断相等

环检测本身不难,但指针操作的边界稍一松懈就会 crash,尤其是和 LeetCode 测试用例里各种极端结构(空、单节点、自环、长链+小环)打交道时,条件顺序和判空缺一不可。

标签:# 弗洛伊德  # 走到  # 最多  # 尤其是  # 放在  # 就会  # 的是  # 跳过  # 小环  # 链表  # node  # leetcode  # 算法  # 空指针  # 指针  # 循环  # while  # if  # 为什么  # c++  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!