很久沒有用過二叉樹了,最近由於需要用到了,發現很多知識需要鞏固了,中間涉及到乙個演算法就是找任意兩個節點的最近祖先。通過本人回顧和演算,最終提出了下面乙個方法,網上也有很多其他的方式實現,再次僅對自己好幾個小時的工作作個記錄和積累吧! 程式是用c語言寫的,個人覺得如果用c#實現會更加方便。
首先是資料結構定義:
[cpp]
typedef char telemtype;
typedef bool status;
typedef struct bitnodebitnode, * bitree;
其次是建樹,用樹的定義,以先序序列遞迴方式建立。
[cpp]
bitnode * createbitree()
return t;
}
空節點的分隔符本處使用的是「#」,可以用其他字元替代。
查詢最近祖先的基本演算法是遞迴,對每個節點先判斷是否有直接關聯,都沒有就分別獲得各自的直系父節點,遞迴呼叫時需要通過兩個節點的深度來判斷下一次呼叫時用哪個使用父節點。具體實現如下:
[cpp]
//查詢兩個節點的最近的公共祖先節點
bitnode * findnearestancestor(bitnode * root, bitnode* p1, bitnode* p2, int h1, int h2)
if (p1 == p2->lchild || p1 == p2->rchild)
return p2;
if (p2 == p1->lchild || p2 == p1->rchild)
return p1;
if (h1 == h2)
return findnearestancestor(
root,
getparent(root, p1),
getparent(root, p2),
h1 - 1,
h2 - 1);
else
return findnearestancestor(
root,
h1 > h2 ? getparent(root, p1) : p1,
h1 < h2 ? getparent(root, p2) : p2,
h1 > h2 ? h1 - 1 : h1,
h1 < h2 ? h2 - 1 : h2);
}
其中getparent是獲取以root為樹根的樹中p節點的直系父節點,定義如下:
[cpp]
bitnode * getparent(bitnode* root, bitnode * p)
else
} 在主函式中呼叫如下:
[csharp]
int main()
上述使用了getheight函式,用來獲取給定樹中節點p的高度,這個函式的實現耗費了較多時間,主要是以前都是獲取樹的高度,很少獲取指定節點的高度,其實現如下:
[cpp]
//查詢節點p的高度,注意與單純只計算樹的高度不同
int getheight(bitnode* root, bitnode * p, int h = 1)
上述測試使用的先序序列為
abc###de##fg###
對應的二叉樹如下:
a/ \
b d
/ / \
c e f / g
二叉樹的建立以及尋找兩個節點的最近公共祖先
通過輸入乙個按照先序遍歷得出的字串,代表空的子節點,大寫字母代表節點內容,來進行二叉樹的構建 輸入兩個節點x和y,求解距離他們最近的共同祖先,若沒有共同祖先則輸出null 如下 include include include.h using namespace std typedef struct ...
二叉樹中兩個節點的最近公共父節點
這個問題可以分為三種情況來考慮 情況一 root未知,但是每個節點都有parent指標 此時可以分別從兩個節點開始,沿著parent指標走向根節點,得到兩個鍊錶,然後求兩個鍊錶的第乙個公共節點,這個方法很簡單,不需要詳細解釋的。情況二 節點只有左 右指標,沒有parent指標,root已知 思路 有...
找出二叉樹上任意兩個節點的最近共同父節點
include includestruct node void creatree node p,int a,int start,int end 使用 p的原因 要在函式體內修改形參的值,並且這個修改能作用到外面呼叫的實參,用單獨的指標就不行,只能用指標的引用或者指標的指標 else return i...