关于快慢指针的理解

顾名思义,快慢指针分为两个指针,一个是快的指针,一个是慢的指针。快慢指针主要用于判断链表中是否有环的存在。

现在我们设想一个场景:龟兔赛跑,龟和兔在同一起点同时出发,但是兔子的速度大于乌龟的速度。如果此时跑道是环形的,那么兔子一定会在某一时刻追上乌龟,换而言之,它们一定会再次相遇。但是如果是非环形跑道,那么兔子一定会先到终点然后停下来,而乌龟一定是在兔子后面抵达终点。

现在我们把这个场景抽离出来:乌龟就是慢指针,兔子就是快指针,跑道就是链表,起点就是表头节点head,终点就是NULL。

快慢二指针同时从表头head出发进行链表的遍历,如果快指针直接到达了终点NULL,说明此链表无环结构;如果快指针和慢指针相遇,说明快指针追上了慢指针,即此链表有环结构。

具体实现代码如下:

#include<stdbool.h>//因为我们定义的函数返回值是bool,即返回true或false,所以用到这个头文件

struct ListNode {
    int val;
    struct ListNode *next;
};//定义链表的单节点,分为数据域val和指针域next

bool hasCycle(struct ListNode *head) {
    struct ListNode *slow=head;//定义慢指针并使其指向头节点
    struct ListNode *fast=head;//定义快指针并使其指向头节点
    while(fast&&fast->next){/*当(快指针指向的节点不为空 并且 快指针所指向的节点的下一个节点不为 
                              空 时)因为若无环结构,fast一定会比slow先到终点,所以这里无需再判 
                              断slow和slow->next是否为NULL。同时这里还包含了链表为空或者只有一 
                              个头节点的情况,因为这两种情况说明链表肯定无环结构,所以直接返回 
                              false*/
        slow=slow->next;//慢指针往前走一步
        fast=fast->next->next;//快指针往前走两步
        if(slow==fast) return true;/*如果慢指针指向的节点等于快指针指向的节点,那么就说明二指针 
                                     相遇,即说明该链表有环结构*/
    }
    return false;
}

注:if(slow==fast)这里比较的一定是整个节点而非节点中的数据域,有些人可能会写成if(slow->val==fast->val),这是错误的,因为不同的节点的数据域是可以相同的,所以要根据此节点的数据域和指针域同时进行判断,即直接判断节点即可,不必区分指针域还是数据域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值