讀《編程之美》有感—判斷兩個鏈表是否相交

請參照書P233-235.

這道題讓我聯想起幾道關於單向鏈表的經典題目:

  1. 如果判斷一個單項鍊表是否存在環?
  2. 已知一個單向鏈表存在環,如果找出該環的入口點?
  3. 已知兩個鏈表相交,如何找出相交的第一個節點?
  4. 如果對一個單向鏈表進行反轉?
  5. 已知一個單向鏈表,不知道該鏈表的頭指針,已知一個節點的指針,如何將該節點從鏈表中刪除?

題1:設置兩個指針(p1, p2),初始值都指向頭,p1每次前進一步,p2每次前進二步,如果鏈表存在環,則p2先進入環, p1後進入環,兩個指針在環中走動,必定相遇。

題2:根據題1的結果,假定鏈表長爲L,環長爲c,鏈表頭到入口點距離爲x,入口點到相遇點的距離爲y,z爲相遇點回到入口點的距離。

L=x+y+z

假定p1,p2指針相遇時,p2指針在環中走了n圈,則有

x+y=nc

所以,x=nc-y=(n-1)c+(L-x)-y=(n-1)c+z

由公式得出:將p1指向表頭,p2指向相遇點,p1,p2同時一步一步前進,當p1前進x步時,p1剛好在入口點,p2在前進了n-1個環後,也回到入口點,這時兩個指針指向同一個節點,該節點就是入口點。

題3:題跟題2一樣,可以將一個鏈表的尾節點指向另外一個,這樣就問題2一樣的解法了。當然,完成時,記得把指針重新置空。

另外一個辦法,就是分別計算出兩個鏈表的長度,分別爲maxL,minL,分別設置指針p1,p2指向兩個鏈表,p1指針指向長鏈表,p1先前進maxL-minL的距離,然後兩個指針同時前進,當p1和p2指向同一個節點時,該節點即爲相交的第一個節點,如果沒有找到,就表示這兩個鏈表不相交

題4:

解法一:可以設置三個指針,pre,cur,next,pre

node *pre=NULL;

node *next=NULL;

node *cur=head;

while(!cur)

{

next=cur->next;

cur->next=pre;

pre=cur;

cur=next;

}

解法二:使用遞歸

node *newRoot;

node *reverseNode(node *cur)

{

if(!cur || !cur.next)

{

newRoot=root;

return cur;

}

node *tmp= reverseNode(cur->next);

tmp->next=cur;

return cur;

}

題5:因爲不知道鏈表的頭指針,因此當前節點(B)如果被刪除,鏈表將斷裂,因此可以用一個指針指向當前節點(B)的下一個節點(C),然後將下一個節點複製到當前節點,這樣當前節點數據就爲下一個節點的數據了,而且指向了下下個節點,然後刪除C節點。

 

附上《編程之美》該題的三頁:

發佈了30 篇原創文章 · 獲贊 15 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章