入二叉樹中的兩個結點,輸出這兩個結點在數中最低的共同父結點。
分析:求數中兩個結點的最低共同結點是面試中經常出現的乙個問題。這個問題至
少有兩個變種。
第一變種是二叉樹是一種特殊的二叉樹:查詢二叉樹。也就是樹是排序過的,位於
左子樹上的結點都比父結點小, 而位於右子樹的結點都比父結點大。 我們只需要從根結點開
始和兩個結點進行比較。 如果當前結點的值比兩個結點都大, 則最低的共同父結點一定在當
前結點的左子樹中。 如果當前結點的值比兩個結點都小, 則最低的共同父結點一定在當前結
點的右子樹中。
第二個變種是樹不一定是二叉樹,每個結點都有乙個指標指向它的父結點。於是我
們可以從任何乙個結點出發, 得到乙個到達樹根結點的單向鍊錶。 因此這個問題轉換為兩個
單向鍊錶的第乙個公共結點。
思路:現在我們回到這個問題本身。所謂共同的父結點,就是兩個結點都出現在這個結點
的子樹中。假如我們從頭部開始遍歷,一旦發現有節點和兩個節點中的乙個相等,那麼此節點就是目標節點,要麼公共父節點在左子樹,要麼在右子樹。如果發現兩個節點乙個在左子樹,乙個在右子樹,那麼當前節點就是公共父節點,如果發現有都在右子樹,那麼公共父節點就在右子樹,如果發現都在左子樹,那麼公共父節點在右子樹
bool findnode(bintree* root,bintree* node)
bintree* lcp(bintree* root,bintree* first,bintree* second)
else
}
另一種實現:
/*
求二叉樹中兩個節點的最低公共祖先節點
*/bintree* lca(bintree* root,bintree* first,bintree* second)
其實找最低公共祖先這個題目還是很有意思的,從第二種實現來看,我們可以思考乙個問題,假如這兩個節點有公共祖先的話,那麼如果當前的節點和兩個節點中的乙個相同,那麼說明當前節點就是公共祖先,如果都不相同,那麼按理來說應該由更加低階別的公共祖先,我們嘗試著再往低的級別找公共祖先,(注意這個時候仍然不排除當前節點是兩個節點的公共祖先),我們從左子樹和右子樹都查詢更加低的公共祖先,如果在左子樹沒有找到,那麼就返回在右子樹查詢的結果,這個時候如果右子樹又結果,那麼它的結果就是最低公共祖先,如果在右子樹中沒有找到,那麼說明這兩個節點沒有最低公共祖先。
如果左子樹查詢到了結果。left != null,那麼就看一下right是否為null,如果right != null 那麼說明在左右兩個子樹中都查詢到了公共祖先,那麼說明最低的公共祖先就是當前的節點!
三、也可以使用最原始的這種方法
既然讓找最低的公共祖先,那麼我們就分別從根節點找兩個節點的路徑,兩天路徑中從前往後看,最後乙個相同的幾點就是最低公共祖先。淡然找路徑的問題就是回溯剪枝問題。這種解決方法在後續的某篇文章中有介紹。
我們再看分析一下這個題目,第一次看到這個題目可能無從下手,但是慢慢琢磨一下,最低的公共祖先,如果當前節點和其中的兩個中的某乙個相同,那麼就是當前祖先,然後再判斷左子樹中是否有其中的某乙個節點,然後根據這個結果就可以進行下面的操作。也就是本篇文章中第一宗解決方法。第三種解決方法就是不使用遞迴的方法。
二叉樹兩個結點的最低共同父結點
需要思考為什麼採用inorder遍歷是可以的?其他遍歷方式結果不正確?include templateclass treenode t value treenode left treenode right templateclass visitcontext treenode node1 treen...
二叉樹兩個結點的最低共同父結點
輸入二叉樹中的兩個結點,輸出這兩個結點在數中最低的共同父結點。網上看來的題目,以下都有參考。求數中兩個結點的最低共同結點是面試中經常出現的乙個問題。這個問題至少有兩個變種。第一變種是二叉樹是一種特殊的二叉樹 查詢二叉樹。也就是樹是排序過的,位於左子樹上的結點都比父結點小,而位於右子樹的結點都比父結點...
二叉樹兩結點的最低共同父結點
題目 求二叉樹兩節點的最低共同父節點 求node節點是否在head樹中 bool findnode tree head,tree node tree findlastfather tree head,tree node1,tree node2 if leftnode1 leftnode2 bool ...