快慢指針【轉載】

1 快慢指針

概念:所謂快慢指針中的快慢指的是指針向前移動的步長,每次移動的步長較大即爲快,步長較小即爲慢,常用的快慢指針一般是在單鏈表中讓快指針每次向前移動2,慢指針則每次向前移動1。

應用:提高查找性能性能

2 如何快速找出未知長度單鏈表的中間節點?

普通方法:先遍歷一遍單鏈表確定其長度L後,再從頭節點出發循環L/2次即可查找到單鏈表的中間節點。該問題如果採用普通的方法雖然簡單,但是查找效率太低。

快慢指針:設置兩個指針*fast*slow都指向單鏈表的頭節點,其中*fast的移動速度是*slow的2倍,當*fast指向末尾節點的時候,slow正好就在中間了,可以大大提高查找的效率。

當然,此時算法還要考慮鏈表結點個數的奇偶數因素,當快指針移動x次後到達表尾(1+2x),說明鏈表有奇數個結點,直接返回慢指針指向的數據即可。如果快指針是倒數第二個結點,說明鏈表結點個數是偶數,這時可以實際情況返回上中位數下中位數(上中位數+下中位數)/2

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;
  }
}

3 如何快速檢測單鏈表是否存在循環?

利用快慢指針的原理,同樣設置兩個指針*fast*slow都指向單鏈表的頭節點,其中*fast的移動速度是*slow的2倍。如果*fast=NULL,說明該單鏈表以NULL結尾,不是循環鏈表;如果*fast=*slow,則快指針追上慢指針,說明該鏈表是循環鏈表。

fast=slow=head;
fast=fast->next->next;
whiletrue{
    if (fast==NULL || fast->next==NULL)//不存在循環
        return false;
    else if (fast==slow || fast->next==slow)//存在循環
        return true;
    else{
        fast=fast->next->next;
        slow=slow->next;
}

以上內容來自於:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章