1.什么是带环链表?
定义:
带环链表是一种单向链表,其中最后一个节点指向链表中的一个先前的节点,从而形成了一个环。环的存在使得链表在遍历时可能出现无限循环的情况。
带环链表可以通过将链表的最后一个节点的指针指向链表中任意一个节点来创建。通常情况下,我们使用一个特殊的节点(称为"哨兵节点")来表示链表的结束,从而形成一个循环。在带环链表中,每个节点都有一个指针指向下一个节点,最后一个节点的指针指向一个前面的节点,而非null。
带环链表常用于实现循环队列、循环链表等数据结构。判断一个链表是否带环可以使用快慢指针的方法,如果存在环,则快指针会在某个时刻追上慢指针。
以下是一个示意图,展示了一个带环链表的结构:
1 -> 2 -> 3 -> 4 -> 5
^ |
| |
+---------+
在上面的示例中,链表的最后一个节点指向了节点2,形成了一个环。
2.什么是快慢指针?
快慢指针是一种常用的技巧,在解决一些链表和数组相关的问题时非常有用。它们分别是指针在遍历链表或数组时的移动速度不同。
快指针(也称为快速指针)会一次移动多个单位,而慢指针(也称为慢速指针)一次只移动一个单位。通过控制快慢指针的移动,可以找到链表中的环、计算链表的中间节点等。
一般情况下,快指针每次移动两个单位,慢指针每次移动一个单位。在遍历链表或数组时,快慢指针可以以不同的方式移动,根据具体问题的要求来确定移动方式。常见的移动方式有:
- 快指针每次移动一步,慢指针每次移动一步。这种移动方式可以用来找到链表的中间节点。
- 快指针每次移动两步,慢指针每次移动一步。这种移动方式可以用来判断链表是否有环,以及找到链表中环的入口节点。
- 快指针每次移动三步、四步等,慢指针每次移动一步。根据具体问题的要求,可以调整快慢指针的移动速度。
通过利用快慢指针的移动速度差异,可以在时间复杂度为O(n)的情况下解决一些链表和数组的问题。
例如常见案例:
//例如在找中间结点的时候可以用快慢指针解决问题
while(fast&&fast->next)//此处分奇数偶数情况
{ //slow走一步,fast走两步
slow=slow->next;
fast=fast->next->next;
}
3.快慢指针的追击问题
那么问题来了,为什么在带环链表中慢指针可以追上快指针?
如图是一个带环链表:
4.返回带环链表第一个交点及相关证明