链表快慢指针原理及应用

快慢指针指两个移动速度不同的指针,多为2倍关系,快慢指针多用来查找链表中点、判断链表是否为环链、计算环链入口。

查找链表中点

设置快慢两个指针,其中快指针每次移动两个节点、慢指针每次移动一个节点,当快指针到达链表结尾时,慢指针所处的位置即链表中点处,该应用在leetcode109题有考察,简单代码如下:

while (fast&&slow)
{
  if (fast->next==NULL)
      return slow ->data;
  else if (fast->next!= NULL && fast->next->next== NULL)
      return (slow ->data + slow ->next->data)/2;
  else
  {
      fast= fast->next;
      fast= fast->next;
      slow = slow ->next;
  }
 }

判断链表是否为环链

判断是否为环链的思想很常见,当链表是环链时,快指针总是可以追上慢指针,跟操场上两个速度不同的人跑圈是一样的道理,代码示意如下:

bool isExitsLoop(LinkList *L) {
    LinkList *fast, *slow;
    fast = slow = L;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
        {
            break;
        }
    }
    return ((fast == NULL) || (fast->next == NULL));
}

计算环链入口

这里直接搬运别人博客上的内容,

假设慢指针进入环中时,即连接点p,快指针(q)需要m步才能追上慢指针。

p和q第一次相遇时,碰撞点在pq处。此时,p走到pq时用了m步。

 假设head到p的距离为a,环长度为Length环,慢指针走了s步,则快指针走了2s步。

从上图可知:

s = a + m

2s = a + m + n * Length环(n为快指针绕环的圈数)

可得

a = n * Length环 - m

因此,设n为1,则a = Length环 - m

也就是:若在头结点(head)和相遇结点(pq)分别设一指针,同步(单步)前进,则最后一定相遇在环入口结点p。

代码示意如下:

node* findLoopPort(node *head) {
    node *fast, *slow;
    fast = slow = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) {
            break;
        }
    }
    if ((fast == NULL) || (fast->next == NULL)) {
        return NULL;
    }
    slow = head;
    while (slow != fast) {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

参考链接:https://www.cnblogs.com/hxsyl/p/4395794.html

https://www.cnblogs.com/songdechiu/p/6686520.html

猜你喜欢

转载自blog.csdn.net/happyjume/article/details/85242926