二叉樹兩個節點的公共節點

2021-06-05 19:56:53 字數 2487 閱讀 1359

**:

很流行的乙個問題,常見於各種面試中, 這裡有乙個很好的彙總.

情況1. 節點只有left/right,沒有parent指標,root已知

情況2. root未知,但是每個節點都有parent指標

情況3. 二叉樹是個二叉查詢樹,且root和兩個節點的值(a, b)已知

雖然情況一是第乙個情況,但是看上去比較複雜,我們放到最後來說,先從第二個情況開始說。

10/       /

6         14

/  /       /   /

4   8   12   16

/  /

3   5

畫乙個二叉樹來做例子。如果我們要找3和8這兩個節點的公共父親節點,我們的做法是首先找到3到根節點的路勁,然後找到8到根節點的路徑。

10//

/6         14

/ /        /   /

4   8   12   16

/   /

3   5

3的路徑用紅色表示,8的用綠色表示,可以看到, 這裡的問題實際上是另乙個我們熟知的問題,有2個相交的單鏈表,找出它們的相交點!

只要把這個二叉樹的倒過來看,或者把脖子倒過來看就知道了:)那個方法也是傳統的求出linkedlist a的長度lengtha, linkedlist b的長度lengthb。然後讓長的那個鍊錶走過abs(lengtha-lengthb)步之後,齊頭並進,就能解決了。

[cpp]view plain

copy

intgetlength (bstnode* pnode)  

return

length;  

}  bstnode* findlcacase2(bstnode* pnode1, bstnode* pnode2)  

piter1 = ptemp;  

piter2 = pnode2;  

}  else

piter1 = pnode1;  

piter2 = ptemp;  

}  while

(piter1&&piter2&&piter1!= piter2)  

return

piter1;  

}  

自己寫了個**,總覺得有些拖沓冗餘,希望有緣人看到文章之後能幫我改寫的更和諧一些。

還是原來這個圖,情況三,如果是個二叉搜尋樹,而且root和a, b已知,我們這個case假設a,b=3,8。從知道根這個條件我們很自然聯想到遞迴(當然不遞迴也可以)地往下找。關鍵是收斂條件,什麼情況下可以判斷出當然檢查的這個節點是最近父親節點呢?其實從這個例子已經可以看出一些端倪了,如果當前訪問的節點比a,b來的都小,肯定不行。如果比a,b都大,也不行。那也就是說,這個節點只有在a<=node<=b的區間內才成立(我們假定a

[cpp]view plain

copy

bstnode* findlcacase3(bstnode* pnode, 

intvalue1, 

intvalue2)  

return

null;  

}  

好,前面的問題都解決了,我們再回過頭來看第乙個情況,只有root和left, right節點,沒有parent也不是排序樹,怎麼辦?網路上也流傳著很多所謂的lca,rmq演算法,我們不暇找個最合適的,尤其是在面試的時候,特定時間空間下你很難寫出乙個邏輯非常複雜的東西(比如你會在面試的時候去實現乙個suffix tree還是用動態規劃來求最長公共子串,哪怕效率不同,我也選擇動態規劃:))。所以這裡,碰到類似的問題的時候,我選擇簡單的記錄找到node1和node2的路徑,然後再把它們的路徑用類似的情況二來做分析,比如還是node1=3,node2=8這個case.我們肯定可以從根節點開始找到3這個節點,同時記錄下路徑3,4,6,10,類似的我們也可以找到8,6,10。我們把這樣的資訊儲存到兩個vector裡面,把長的vector開始的多餘節點3扔掉,從相同剩餘長度開始比較,4!=8, 6==6, coooool,我們找到了我們的答案。下面的**完全按照這個思路寫成

[cpp]view plain

copy

#include 

bool

nodepath (bstnode* proot, 

intvalue, std::vector& path)  

else

else

return

false

;  }  

}  else

}  bstnode* findlcacase1(bstnode* pnode, int

value1, 

intvalue2)  

}  }  return

preturn;  

}  

這段**經歷了大概30分鐘的修改和debug,然後才逐漸穩定下來,真的很難想象如果是在面試的環境下,在紙筆之上會有如何的表現,可能真是只有天知道了。

二叉樹中兩個節點的最近公共父節點

這個問題可以分為三種情況來考慮 情況一 root未知,但是每個節點都有parent指標 此時可以分別從兩個節點開始,沿著parent指標走向根節點,得到兩個鍊錶,然後求兩個鍊錶的第乙個公共節點,這個方法很簡單,不需要詳細解釋的。情況二 節點只有左 右指標,沒有parent指標,root已知 思路 有...

求二叉樹兩個節點的最近公共祖先

偶然看到乙個特別特別巧妙的方法,在此記錄一下 typedef struct xbnodexbnode,xbtree 取名叫xbtree是因為以為這個是線索二叉樹 記住!這個不是線索二叉樹,線索二叉樹是儲存了前驅和後繼的指標,包括前序線索二叉樹 中序線索二叉樹和後序線索二叉樹三種。由於建立的時候多了乙...

二叉樹中兩個節點的最低公共祖先

求二叉樹樹中的兩個節點的最低公共祖先是個有趣的問題,涉及到對遞迴的理解。可以參考部落格 下面是乙個簡單的複雜度為 o n 的演算法,解決lca問題 1 找到從根到n1的路徑,並儲存在乙個向量或陣列中。2 找到從根到n2的路徑,並儲存在乙個向量或陣列中。3 遍歷這兩條路徑,直到遇到乙個不同的節點,則前...