判斷單鏈表中是否有環,計算出環的首位址 C語言實現

2021-09-30 11:31:09 字數 2599 閱讀 9910

判斷單鏈表中是否有環,如果有,得出進入環時首個節點的位址.

有環的定義是,鍊錶的尾節點指向了鍊錶中的某個節點。

如:           ____________

那麼要判斷單鏈表中是否有環,主要有以下兩種方法:

方法一:

使用p1、p2兩個指標指向頭節點,p1總是向前走,但p2每次都從頭開始走,對於每個節點,看p1走的步數是否和p2一樣。如圖,當p1從6走到3時,用了6步,此時若p2從head出發,則只需兩步就到3,因而步數不等,出現矛盾,存在環。而且這個點就是進入環時首個節點。(參考函式plink check_link_1(plink head))

方法二:

使用p1、p2兩個指標指向頭節點,p1每次向前走一步,p2每次向前走兩步,若在某個時候p1 == p2,則存在環。然後p2指向頭結點,使p1,p2每次向前走一步,進行比較p1,p2如果p1==p2那麼這個節點就是入環時首個節點。

演算法如下:如上圖所示,如果①節點到③節點的距離為x,假設第一次移動時,p1 == p2時的節點是⑤的話,③到⑤的距離為y, ③到的距離為z。  所以我們可以得到第一次p1==p2時,那麼p1和p2走的步數的差就是p1走過的步數,而且是z的倍數。x+y+mz=nz,所以x+y=(m-n)z。所以當x+y向前移動x時肯定會到達入環時首個節點。 x+y+x=(m-n)z+x。這樣我們就可以求得入環首節點的的位址了。(參考函式plink check_link_1(plink head))

**如下所示:

/*

* 判斷單鏈表中是否有環,如果有,得出進入環節點的首位址.

*/#include #include typedef struct link*plink;

#define link_max 10

/* 建立乙個單鏈表 */

void create_link(plink *head, int num)

(*head)->data = num;

(*head)->next = null;

return;

} node = *head;

while(node->next != null)

next = (plink)malloc(sizeof(struct link));

if(next == null)

next->data = num;

next->next = null;

node->next = next;

return;

}/* 在單鏈表中設定乙個環,讓尾節點指向鍊錶中的第n個節點 */

int create_loop(plink *head, int n)

while(node->next != null)

node = node->next;

count++;

} /* 尾節點和自身成乙個環時 */

if(count == n)

if(n_node == null)

node->next = n_node;

return 0;

}/* 列印鍊錶的前n個data的值 */

void print_link(plink head, int n)

printf("\n");

return;}/*

* 使用p1、p2兩個指標,p1總是向前走,但p2每次都從頭開始走,

* 對於每個節點,看p1走的步數是否和p2一樣。數不等,存在環。

* 而且該點就是入環時首個節點的位址。

*/plink check_link_1(plink head)

if((p1 == p2) && (count1 != count2))

p1=p1->next;

count1++;

} return null;}/*

* 使用p1、p2兩個指標,p1每次向前走一步,p2每次向前走兩步,

* 若在某個時候p1 == p2,則存在環.

* 然後p1繼續向前走,p2重頭開始一步一步向前走,當p1 == p2時,

* 那麼該點就是入環時首個節點的位址

*/plink check_link_2(plink head)

if(p1 == p2)

} if(flag)

return p1;

} return null;

}/* 刪除鍊錶 */

void delete_link(plink *head)

int main()

/* 在單鏈表中設定乙個環,讓尾節點指向鍊錶中的第n個節點 */

n = 5;

ret = create_loop(&root,n);

if(ret)else

/* 列印鍊錶 */

n = 20;

print_link(root,n);

/* 檢查該環 */

node = check_link_1(root);

if(node == null)else

/* 刪除鍊錶 */

delete_link(&root);

return 0;

}

判斷單鏈表中是否有環

define crt secure no deprecate include include include include define ok 1 define error 0 define true 1 define false 0 typedef int status 函式結果狀態 如ok。t...

判斷單鏈表中是否有環

單鏈表中的迴圈鍊錶尾結點不一定指向頭結點,也可以指向任意中間結點。此時若想判斷單鏈表中是否有環,就不能只是簡單的根據尾結點的next是不是頭結點來判斷,在此我提供三種方法 方法一 建立兩個指標p和q,其中p用來遍歷指標,每次只走一步,並記錄從根節點出發所走的步數,而q則是每次從根節點出發,到達p此時...

判斷單鏈表是否有環

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