連結串列是否有環的兩種判斷方法
阿新 • • 發佈:2019-02-07
判斷單鏈表是否有環
假設有一個含環連結串列:1-2-3-4-5-6-3(6又連線到3,形成一個環)
- 使用p、q兩個指標,p總是向前走,但q每次都從頭開始走,對於每個節點,看p走的步數是否和q一樣。當p從6走到3時,用了6步;此時q從head出發,則只需兩步就到3,因而步數不等,出現矛盾,存在環。而且可以鎖定環的位置,就是q的步數+1
- 使用p、q兩個指標,p每次向前走一步,q每次向前走兩步,若在某個時候p == q,則存在環。雖然無法鎖定環的位置,但是佔用空間和時間少。這就是之前說的快慢連結串列裡面的快慢指標。
實現:
#include<iostream> #include<cstdio> using namespace std; const int MAXLEN = 6; struct Node{ int val; Node *next; }; int IfLoop(Node *head){ Node * cur1 = head; int pos1 = 0; while(cur1){ Node * cur2 = head; int pos2 = 0; pos1++; while(cur2){ pos2++; if(cur2==cur1){ if(pos1==pos2) break; else return pos2; } cur2 = cur2->next; } cur1 = cur1->next; } return -1; } bool IfLoop_2(Node *head){ Node * p = head; Node * q = head; while(p && q){ p = p->next; q = q->next; if(q) q = q->next; if (p && p==q) return true; } return false; } int main(){ Node *head = new Node; head->val = 0; Node *s = new Node; Node *p = new Node; head->next = p; for(int i=0;i<MAXLEN;++i){ p->val = i+1; p->next = s; p =s; s = new Node; } p->next = head->next->next; cout<<"位置在:"<<IfLoop(head)<<",如果位置是-1,則不存在"<<endl; return 0; }