2010-10-26 16:03:37
| 分類:
資料結構與演算法
| 標籤:
proot
節點pleft
pright
nmaxleft|字型大小
大中小訂閱
如果我們把二叉樹看成乙個圖,父子節點之間的連線看成是雙向的,我們姑且定義「距離」為兩個節點之間邊的個數。
寫乙個程式求一顆二叉樹中相距最遠的兩個節點之間的距離。
如圖3-11所示,粗箭頭的邊表示最長距離:
分析與解法
我們先畫幾個不同形狀的二叉樹,(如圖3-12所示),看看能否得到一些啟示。
從例子中可以看出,相距最遠的兩個節點,一定是兩個葉子節點,或者是乙個葉子節點到它的根節點。(為什麼?)
解法一根據相距最遠的兩個節點一定是葉子節點這個規律,我們可以進一步討論。
對於任意乙個節點,以該節點為根,假設這個根有k個孩子結點,那麼相距最遠的兩個節點u和v之間的路徑與這個根節點的關係有兩種情況:
1. 若路徑經過根root,則u和v是屬於不同子樹的,且它們都是該子樹中道根節點最遠的節點,否則跟它們的距離最遠相矛盾。這種情況如圖3-13所示:
2. 如果路徑不經過root,那麼它們一定屬於根的k個子樹之一。並且它們也是該子樹中相距最遠的兩個頂點。如圖3-14中的節點a:
因此,問題就可以轉化為在字數上的解,從而能夠利用動態規劃來解決。
設第k棵子樹中相距最遠的兩個節點:uk和vk,其距離定義為d(uk,vk),那麼節點uk或vk即為子樹k到根節點rk距離最長的節點。不失一般性,我們設uk為子樹k中道根節點rk距離最長的節點,其到根節點的距離定義為d(uk,r)。取d(ui,r)(1<=i<=k)中最大的兩個值max1和max2,那麼經過根節點r的最長路徑為max1+max2+2,所以樹r中相距最遠的兩個點的距離為:max。
採用深度優先搜尋如圖3-15,只需要遍歷所有的節點一次,時間複雜度為o(|e|)=o(|v|-1),其中v為點的集合,e為邊的集合。
示例**如下,我們使用二叉樹來實現該演算法。
//資料結構定義
struct node
;int nmaxlen=0;
//尋找樹中最長的兩段距離
void findmaxlen(node* proot)
//如果左子樹為空,那麼該節點的左邊最長距離為0
if(proot->pleft==null)
//如果右子樹為空,那麼該節點的右邊最長距離為0
if(proot->pright==null)
//如果左子樹不為空,遞迴尋找左子樹最長距離
if(proot->pleft!=null)
//如果右子樹不為空,遞迴尋找右子樹最長距離
if(proot->pright!=null)
if(proot->pleft!=null)
//計算右子樹最長節點距離
if(proot->pright!=null)
//更新最長距離
if(proot->nmaxleft+proot->nmaxright > nmaxlen)
nmaxlen=proot->nmaxleft+proot->nmaxright;}
求二叉樹中節點的最大距離
遞迴求解,最大距離總是在一下兩種情況產生 情況1 最大路徑經過root 這個例子中,最長路徑經過root,其距離等於左子樹的高度 1 右子樹的高度 1 在這種情況下 如果只有左子樹,右子樹為空 最大距離 左子樹的高度 1 如果只有右子樹,左子樹為空 最大距離 右子樹的高度 1 如果既有右子樹,又有左...
求二叉樹中節點的最大距離
如果我們把二叉樹看成乙個圖,父子之間的連線看成,姑且定義 距離 為兩個之間邊的個數。求一顆二叉樹中相距最遠兩個點之間的距離。struct node bittree int nmaxlen 0 void findmaxlen node proot if proot pleft null if proo...
求二叉樹中節點的最大距離
今天中午的時候有人問了我乙個問題 求二叉樹中節點的最大距離。這是 程式設計之美 上的乙個問題。花了一中午的時間總算解決了這個問題,有一點是很明確的 如果把樹看做是乙個圖的話,它必然是連通的,任一節點總有路徑到其他任何節點,這個題目就是求這樣最長的一條路徑。距離最大的兩個節點可能是乙個在左子樹,乙個在...