單鏈表是否存在環

2021-07-16 08:42:33 字數 1681 閱讀 1527

給定乙個單鏈表,只給出頭指標h:

1、如何判斷是否存在環?

2、如何知道環的長度?

3、如何找出環的連線點在**?

4、帶環鍊錶的長度是多少?

解法:

1、對於問題1,使用追趕的方法,設定兩個指標slow、fast,從頭指標開始,每次分別前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到null退出。

2、對於問題2,記錄下問題1的碰撞點p,slow、fast從該點開始,再次碰撞所走過的運算元就是環的長度s。

3、問題3:有定理:碰撞點p到連線點的距離=頭指標到連線點的距離,因此,分別從碰撞點、頭指標開始走,相遇的那個點就是連線點。(證明在後面附註)

4、問題3中已經求出連線點距離頭指標的長度,加上問題2中求出的環的長度,二者之和就是帶環單鏈表的長度

void isloop(llink head)

}if(!loop)

cout<<"this link has not loop\n";

else

while(p!=r);

--loopcount;

while(p!=q)//得到環的入口結點,同時計算得到非環的結點數

--nonloop;

cout<<"\nstart of loop: "cout<<"\ncount of nonloop: "<

<<"\ncount of loop: "<

<<"\ncount of linknode: "<}}

判斷是否存在環的程式:

bool i***itsloop(slist *head)  

return !(fast == null || fast->next == null);  } 

尋找環連線點(入口點)的程式:

slist* findloopport(slist *head)  

if (fast == null || fast->next == null) 

return null; 

slow = head; 

while (slow != fast)   

return slow;  } 

亦可以用類似與hash表的方法,即設立乙個陣列,將鍊錶結點中的值做陣列下標,當賦值衝突時就是環的接入點

bool isloop(llink p)

a[p->data]=-1;

++n;

p=p->next;

}return false;

}llink creatlinkloop()

//建立乙個有環的鍊錶

cin.clear();

cin.sync();

srand(time(0));

q->next=findnode(head,rand()%n);//隨機產生環的接入點

return head;

}llink findnode(llink head,int n)//找出鍊錶中的第n個結點

判斷單鏈表是否存在環

有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...

判斷單鏈表是否存在環

判斷單鏈表是否存在環,判斷兩個鍊錶是否相交問題詳解 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如何找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 ...

判斷單鏈表是否存在環

問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。當然,...