題目:輸入兩個樹結點,求它們的最低公共祖先
題目一:如果這個樹是二叉搜尋樹,二叉搜尋樹是排序過的,位於左子樹的結點都比父結點小,而位於右子樹的結點都比父結點大,我們只需要從樹的根結點開始和兩個輸入的結點比較,如果輸入兩個結點都比根結點小,那麼最低的共同父結點一定在當前結點的左子樹中,於是下一步遍歷當前結點的這左子結點。如果當前結點的值比兩個結點都小,那麼最低共同父結點一定在當前結點的右子樹中,於是下一步遍歷當前結點的右子結點。這樣在樹中從上到下找到的第乙個在兩個輸入結點的值之間的結點,就是最低的公共祖先。
題目二:如果這個樹不是二叉搜尋樹,不是二叉樹,只是普通的數。如果樹的結點有指向父結點的指標,那麼可以轉換為求兩個鍊錶的第乙個公共交點,就是他們的最低公共祖先。
題目三:普通的樹,樹中的結點沒有指向父結點的指標。
我們首先得到一條從根結點到樹中某一結點的路徑,這就要求在遍歷的時候,有乙個輔助記憶體來儲存路徑.比如我們用前序遍歷的方法來得到從根結點到h 的路徑的過程是這樣的:( 1 )遍歷到a,把a 存放到路徑中去,路徑中只有乙個結點a; ( 2 )遍歷到b,把b 存到路徑中去,此時路徑為a->b; ( 3 )遍歷到d,把d 存放到路徑中去,此,時路徑為a->b->d; ( 4 ) :遍歷到f,把f 存放到路徑中去,此時路徑為a->b->d->f;( 5) f 已經沒有子結點了,因此這條路徑不可能到這結點h. 把f 從路徑中刪除,變成a->b->d; ( 6 )遍歷g. 和結點f 一樣,這條路徑也不能到達h. 邊歷完g 之後,路徑仍然是a->b->d; ( 7 )由於d 的所有子結點都遍歷過了,不可能到這結點h,因此d 不在從a 到h 的路徑中,把d 從路徑中刪除,變成a->b; ( 8 )遙歷e,把e 加入到路徑中,此時路徑變成a->b->e, ( 9 )遍歷h,已經到達目標給點, a->b->e 就是從根結點開始到達h 必須經過的路徑。
同樣,我們也可以得到從根結點開始到達f 必須經過的路徑是a->b功。接著,我們求出這兩個路徑的最後公共結點,也就是b. b這個結點也是f 和h 的最低公共祖先.
為了得到從根結點開始到輸入的兩個結點的兩條路徑,需要追歷兩次樹,每邊歷一次的時間複雜度是o(n).得到的兩條路徑的長度在最差情況時是0(時,通常情況丁兩條路徑的長度是o(logn).
思路三**如下:
bool getnodepath(treenode* proot,treenode* pnode,list&path)
if(!found)
path.pop_back();
return found;
}treenode* getlastcommonnode(const listpath1,const listpath2)
return plast; }
treenode* getlastcommonparent(treenode* proot,treenode* pnode1,treenode* pnode2)
樹中兩個結點的最低公共祖先
在進行這個問題之前,我們需要考慮以下幾個問題 1 題目告訴我們是樹,但是沒有告訴我們是一棵怎樣的樹。這裡的樹可以分為三種結構。第一種 普通的二叉樹 第二種 結點中含有指向父親結點的指標 第三種 二叉搜尋樹。2 對於不同結構的樹,處理的方式是不一樣的,時間複雜度也是不一樣的,我們需要針對每種結構設計解...
樹中兩個結點的最低公共祖先
場景一 二叉搜尋樹bst 假設是二叉搜尋樹 二叉搜尋樹是乙個排序的二叉樹,左子樹的結點小於根結點,右子樹的結點大於根結點 故找到乙個結點,使其大於左子結點小於右子結點即可。public static treenode getlastcommonnode treenode proot,treenode...
樹中兩個結點的最低公共祖先
遇到這個題要分幾種情況 1 該樹是一棵二叉搜尋樹 由於二叉搜尋樹是排序過的,位於左子樹的結點都比父節點小,而位於右子樹的結點都比父節點大,我們只需要從樹的根節點開始和兩個輸入的結點進行比較。如果當前結點的值都比兩個結點的值大,那麼最低的共同父節點一定是在當前結點的左子樹中,於是下一步遍歷當前結點的左...