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

2021-08-20 15:00:39 字數 1610 閱讀 3090

偶然看到乙個特別特別巧妙的方法,在此記錄一下~

typedef struct xbnodexbnode,*xbtree;
取名叫xbtree是因為以為這個是線索二叉樹 > < 記住!這個不是線索二叉樹,線索二叉樹是儲存了前驅和後繼的指標,包括前序線索二叉樹、中序線索二叉樹和後序線索二叉樹三種。

由於建立的時候多了乙個parent指標,所以注意要把該節點的parent作為引數傳遞。這種寫法的時候還需要注意最後不要忘記return節點,不然就建了乙個空樹啦~

xbtree createxbtree(xbtree tree)

xbtree xb = (xbtree)malloc(sizeof(xbnode));

xb->data = e;

xb->parent = tree;

xb->lchild = createxbtree(xb);

xb->rchild = createxbtree(xb);

return xb;

}

根據使用者輸入的字元找到該節點,也用遞迴的方法,判斷是否是為空,判斷是否是該字元,如果不是再遍歷左樹和右樹。

xbtree getposition(xbtree p, char e,xbtree &out)

if (p->data == e)

getposition(p->lchild, e,out);

getposition(p->rchild, e,out);

}

這個就是最簡單的思路,採用二重迴圈遍歷出所有有可能的情況,時間複雜度為o(n^2)。

char getancestor(xbtree tree, char x1, char x2)

xbtree q1 = p1;

xbtree q2 = p2;

while (q1 != null)

while (q2 != null)

q2 = q2->parent;

}q1 = q1->parent;

q2 = p2;

}return null;

}

這種暴力的方法很容易理解,但是時間複雜度較高!

可以換一種方式理解,這兩個節點分別和他們的parent們可以構成乙個鍊錶:

然後這個問題就轉換為如何求兩個鍊錶的交點。求解的時候也有乙個很巧妙的方法,從兩個鍊錶的頭開始遍歷,當某個鍊錶遍歷到根節點的時候使其等於另外乙個鍊錶的頭,比如鍊錶1的長度為m,鍊錶2的長度n,交點在a位置,那麼鍊錶1需要next 這麼多次 m+(n-a)正好到交點a,鍊錶2需要next這麼多次 n + (m-a)正好到交點a,發現沒有!正好同時遍歷到交點a!附上**:

xbtree q1 = p1;

xbtree q2 = p2;

while (q1->data != q2->data)

return null;

這樣時間複雜度就只有o(n)了,真的感覺這個方法特別巧妙!!!

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

比如 在如圖這棵二叉樹中,8和9的公共祖先是1,4和5的公共祖先是2,5和2的公共祖先是2。在上述分析中,我們可以得出思路,本題解法可分為兩種情況,1 兩個節點在根節點同側 則它們的最近公共祖先可能是其中乙個節點,也可能是在到兩個節點的公共路徑上。2 兩個節點在根節點的不同側,則它們的公共祖先只能是...

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

要求考慮以下三種種情況,給出解決方案,並解決 1 二叉樹是搜尋二叉樹。2 二叉樹每個節點有parent 三叉鏈 treenode publiclowparent treenode root,treenode c1,treenode c2 else if c1 data cur data c2 dat...

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

1 原理 二叉搜尋樹是排序過的 位於左子樹的結點都比父結點小,位於右子樹的結點都比父結點大,我們只需從根節點開始和兩個輸入的結點進行比較,如果當前節點的值比兩個結點的值都大,那麼最低的公共祖先結點一定在該結點的左子樹中,下一步開遍歷當前結點的左子樹。如果當前節點的值比兩個結點的值都小,那麼最低的公共...