【演算法詳解】有環連結串列
定義:
迴圈連結串列:連結串列中一個節點的next指標指向先前已經存在的節點,導致連結串列中出現環。
問題1:判斷是否有環
#include <cstring>
#include <iostream>
using namespace std;
struct node
{
char value;
node* next;
node(char rhs)
{
value = rhs;
next = NULL;
}
};
bool isLoop(node* head)
{
if (head == NULL)
{
return false;
}
node* slow = head;
node* fast = head;
while((fast!= NULL) && (fast->next != NULL))
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
break;
}
}
return !(fast == NULL || fast->next == NULL);
}
int main()
{
node A('A');
node B('B');
node C('C');
node D('D');
node E('E');
node F('F');
node G('G');
node H('H');
node I('I');
node J('J');
node K('K');
A.next = &B;
B.next = &C;
C.next = &D;
D.next = &E;
E.next = &F;
F.next = &G;
G.next = &H;
H.next = &I;
I.next = &J;
J.next = &K;
K.next = &D;
if (isLoop(&A))
{
cout<<"Loop";
}else
{
cout<<"No loop";
}
return 0;
}
問題2:找到這個環的起始點
輸入: A->B->C->D->E->F->G->H->I->J->K->D
輸出:D
分析:
當fast與slow相遇時, slow肯定沒有遍歷完連結串列,而fast在環內肯定迴圈了1圈以上。
設環的長度為r, 相遇時fast在環內走了n個整圈(n > 1),slow走了s步,fast走了2s步,則:
2s = s + nr -> s = nr
設整個連結串列的長度為L,環入口點與相遇點的距離為x,連結串列起點到環入口點的距離為a,則:
a + x = s = nr (slow走過的步數,slow為走過一圈)
a + x = (n-1)r + r = (n-1)r + (L - a) -> a = (n-1)r + (r - x)
(r - x) 為相遇點到環入口點的距離; 因此,連結串列頭到環入口點的距離 等於 (n-1)個環迴圈 + 相遇點到環入口的距離。
我們從連結串列頭和相遇點分別設定一個指標,每次各走一步,則兩個指標必定相遇,且第一個相遇點為環入口點。
#include <cstring>
#include <iostream>
using namespace std;
struct node
{
char value;
node* next;
node(char rhs)
{
value = rhs;
next = NULL;
}
};
node* isLoop(node* head)
{
if (head == NULL)
{
return false;
}
node* slow = head;
node* fast = head;
while((fast!= NULL) && (fast->next != NULL))
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
break;
}
}
if (fast == NULL || fast->next == NULL)
{
return NULL;
}
// currently, the list is looped
slow = head;
while(slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
int main()
{
node A('A');
node B('B');
node C('C');
node D('D');
node E('E');
node F('F');
node G('G');
node H('H');
node I('I');
node J('J');
node K('K');
A.next = &B;
B.next = &C;
C.next = &D;
D.next = &E;
E.next = &F;
F.next = &G;
G.next = &H;
H.next = &I;
I.next = &J;
J.next = &K;
K.next = &D;
node* p;
if ((p= isLoop(&A))!= NULL)
{
cout<<"Loop, the interaction node is "<<p->value;
}else
{
cout<<"No loop";
}
return 0;
}
相關文章
- 演算法題:反轉一個單連結串列&判斷連結串列是否有環演算法
- Python實現環形連結串列詳解Python
- 【圖解連結串列類面試題】環形連結串列圖解面試題
- 判斷單連結串列是否存在環,判斷兩個連結串列是否相交問題詳解
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 【資料結構】連結串列(單連結串列實現+詳解+原碼)資料結構
- 演算法141. 環形連結串列演算法
- 每日演算法隨筆:環形連結串列演算法
- 環形連結串列II
- 既然已經有陣列了,為什麼還要連結串列?JS連結串列(Linked-list)詳解陣列JS
- 演算法-連結串列演算法
- 連結串列面試題(十一)---求帶環單連結串列 環的入口點面試題
- 連結串列面試題(十)---求帶環單連結串列的環的長度面試題
- 漫畫演算法:如何判斷連結串列有環?演算法
- 環形連結串列_相交連結串列_多數元素(java語言)Java
- 把玩演算法 | 連結串列演算法
- Java單連結串列反轉圖文詳解Java
- Python實現單向連結串列詳解Python
- 連結串列面試題(九)---判斷一個連結串列是否帶環面試題
- 【圖解連結串列類面試題】移除連結串列元素圖解面試題
- 程式碼隨想錄演算法訓練營第4天 | 連結串列兩兩交換、刪除倒N、連結串列相交、環形連結串列演算法
- 約瑟夫環 佇列+連結串列佇列
- 141. 環形連結串列
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- 演算法面試(一) 連結串列演算法面試
- 初級演算法-連結串列演算法
- 力扣--連結串列演算法力扣演算法
- 筆記--連結串列演算法筆記演算法
- 演算法基礎~連結串列~排序連結串列的合併(k條)演算法排序
- 連結串列-雙向連結串列
- 連結串列-迴圈連結串列
- 連結串列面試題(二)---連結串列逆序(連結串列反轉)面試題
- 【小白學演算法】5.連結串列(linked list)、連結串列的新增演算法
- 連結串列面試題(十三)---求兩個都不帶環的連結串列相交的結點面試題
- 連結串列找環(python實現)Python
- 連結串列面試題(八)---約瑟夫環面試題
- 【資料結構之連結串列】詳細圖文教你花樣玩連結串列資料結構
- 演算法題中的連結串列演算法