單鏈表存在環的問題,也就是說明,某個節點的next指針指向的是在它前面的節點。方法有好多種
1.假設存在兩個指針*a,*b都指向鏈表的頭結點,每循環判斷一次,a向前走一步,b向前走兩步。那么如果這樣算下去,總有一個有限循環內,b會到達NULL指針或者b和a相等。此時停止循環。
bool findLoop(node *head)
{
node *a=head;
node *b=head;
if(head==NULL||head->next=NULL)
{
return false;
}
do{
a=a->next;
b=b->next->next;
}while(a!=b&&b&&b->next);
if(a==b)
return true;
else
return false;
}這個答案算是比較靠譜的答案,但很難准確把握算法的時間復雜度,寫完隨筆后又想了想,這的確不是一個好答案。
2.可以循環遍歷單鏈表,對走過的節點進行標記,數據成員全部初始化為0,然后開始遍歷,給數據層編輯數字,0,1,2,3,4,5,……如果當前節點為19,則下個節點為20或者不存在,如果下個節點存在且不為20,則說明鏈表存在環起始環節點為第20個節點,為了保證鏈表中數據的完整性,可采用值傳遞或者const &a形式的傳遞方式,保證鏈表的安全性。
第二種方法從一定程度上來說保證了算法的效率,但為鏈表數據部分歸零時很難保證能夠全部初始化完畢或者無重復,想了想還是用另一種方法,不知道對不對。
3.把節點存放的地址讀取出來,存放進哈希表中,指針后移直到指針指向NULL或者發現哈希表中有地址重復的地方停止,如果發現重復地址,則該指針即為環的出口地址。
(如果鏈表足夠長的話,對哈希表的要求又比較高,所以哪個是最優的很難說。如果碰到面試題目的時候,用第一種方法就可以了)
