二叉樹兩個結點的最低共同父結點

2021-06-08 20:36:22 字數 2912 閱讀 3712

輸入二叉樹中的兩個結點,輸出這兩個結點在數中最低的共同父結點。

網上看來的題目,以下都有參考。求數中兩個結點的最低共同結點是面試中經常出現的乙個問題。這個問題至少有兩個變種。

第一變種是二叉樹是一種特殊的二叉樹:查詢二叉樹。也就是樹是排序過的,位於左子樹上的結點都比父結點小,而位於右子樹的結點都比父結點大。我們只需要從根結點開始和兩個結點進行比較。如果當前結點的值比兩個結點都大,則最低的共同父結點一定在當前結點的左子樹中。如果當前結點的值比兩個結點都小,則最低的共同父結點一定在當前結點的右子樹中。解法對應lastcommonparent_1。

第二個變種是樹不一定是二叉樹,每個結點都有乙個指標指向它的父結點。

解法一:lastcommonparent_2

我們可以定義一函式,來判斷乙個結點的子樹中是不是包含了另外乙個結點。我們可以從根結點開始,判斷以當前結點為根的樹中左右子樹是不是包含我們要找的兩個結點。如果兩個結點都出現在它的左子樹中,那最低的共同父結點也出現在它的左子樹中。如果兩個結點都出現在它的右子樹中,那最低的共同父結點也出現在它的右子樹中。如果兩個結點乙個出現在左子樹中,乙個出現在右子樹中,那當前的結點就是最低的共同父結點。接著我們來分析一下這個方法的效率。函式hasnode的本質就是遍歷一棵樹,其時間複雜度是o(n)(n是樹中結點的數目)。由於我們根結點開始,要對每個結點呼叫函式hasnode。因此總的時間複雜度是o(n2)。不難發現我們判斷以乙個結點為根的樹是否含有某個結點時,需要遍歷樹的每個結點。接下來我們判斷左子結點或者右結點為根的樹中是否含有要找結點,仍然需要遍歷。第二次遍歷的操作其實在前面的第一次遍歷都做過了。由於存在重複的遍歷,本方法在時間效率上肯定不是最好的。

解法二:lastcommonparent_3

我們可以從任何乙個結點出發,得到乙個到達樹根結點的單向鍊錶。因此這個問題轉換為兩個單向鍊錶的第乙個公共結點。

#include #include #include using namespace std;

typedef struct btreenode

btreenode, *btree;

const int invalied = -1;

void createtree(int *tree, btree &rt, int &i);

void preorderre(btree rt);

bool hasnode(btree rt, btreenode *pnode); //以rt為根節點的樹是否含有子節點pnode

bool getnodepath(btree rt, btreenode *pnode, list&path); //與按葉子節點訪問差不多,用bool型別做為返回值是為了當找到時馬上結束遞迴

btreenode* lastcommonparent_1(btree rt, btreenode *pnode1, btreenode *pnode2); //查詢樹的時候

btreenode* lastcommonparent_2(btree rt, btreenode *pnode1, btreenode *pnode2); //一般的二叉樹的演算法一

btreenode* lastcommonparent_3(btree rt, btreenode *pnode1, btreenode *pnode2); //一般的二叉樹的演算法二

int main()

; btree rt = null;

int i = 0;

createtree(tree, rt, i);

btreenode *pnode1 = rt->left->left->left;

btreenode *pnode2 = rt->left->right;

btreenode *pcommon = null;

//pcommon = lastcommonparent_1(rt, pnode1, pnode2);

//pcommon = lastcommonparent_2(rt, pnode1, pnode2);

pcommon = lastcommonparent_3(rt, pnode1, pnode2);

coutcreatetree(tree, rt->left, i);

createtree(tree, rt->right, i);

}void preorderre(btree rt)

}btreenode* lastcommonparent_1(btree rt, btreenode *pnode1, btreenode *pnode2)

bool hasnode(btree rt, btreenode *pnode)

btreenode* lastcommonparent_2(btree rt, btreenode *pnode1, btreenode *pnode2)

if((pnode1lefthas == true && pnode2lefthas == false)||(pnode1lefthas == false && pnode2lefthas == true))

return rt;

if(pnode1lefthas == true && pnode2lefthas == true)

return lastcommonparent_2(rt->left, pnode1, pnode2);

if(rt->right && pnode1lefthas == false && pnode2lefthas == false)

return lastcommonparent_2(rt->right, pnode1, pnode2);

}bool getnodepath(btree rt, btreenode *pnode, list&path)

btreenode* lastcommonparent_3(btree rt, btreenode *pnode1, btreenode *pnode2)

return ret;

}

二叉樹兩個結點的最低共同父結點

需要思考為什麼採用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 ...