今天中午的時候有人問了我乙個問題:求二叉樹中節點的最大距離。這是《程式設計之美》上的乙個問題。
花了一中午的時間總算解決了這個問題,有一點是很明確的:如果把樹看做是乙個圖的話,它必然是連通的,任一節點總有路徑到其他任何節點,這個題目就是求這樣最長的一條路徑。距離最大的兩個節點可能是乙個在左子樹,乙個在右子樹,也可能是在乙個子樹上。下面的圖展示了這兩種情況
我試著把這個問題轉化一下:樹中的每乙個節點都是一顆子樹的根,對於這棵子樹而言,它左子樹的高度是lm,右子樹的高度是rm,求所有子樹中(lm + rm)的最大值是多少?(雖然不知道這樣的問題在實際生產中是否有意義,也許有吧),還是用圖比較直觀。
在圖上標出了每個節點左子樹的長度和右子樹的長度,葉子節點的左右子樹長度都是0。每個節點左子樹的長度是左孩子的左子樹長度和左孩子右子樹長度中較長的那個再加1,,這句話比較繞,但是好理解,比如a->lm = max(b->lm,b->rm) + 1,這樣很明了了吧。有了上面的資訊之後,我們可以計算每棵子樹的(lm + rm),其中最大者就是結果。由於樹的定義是遞迴的,所以用遞迴的方式更容易程式設計。
演算法步驟:
(1)初始化二叉樹,並將每個節點lm和rm初始化為0,定義二叉樹中節點的最大距離max = -1
(2)為了計算乙個節點的lm和rm,需要採用後序遍歷策略,遞迴的計算出它左孩子left的lm,rm,lm = max(left->lm + left->rm) + 1;和右孩子right的lm,rm,rm = max(right->lm,right->rm) + 1;
(3)對於每乙個節點,計算lm + rm,如果其值大於max,則max = lm + rm,最後max就是最大距離。
樹節點的宣告如下:
typedef struct treenode *position;
typedef position tree;
struct treenode ;
static int max = -1;//儲存最遠的距離
實際演算法如下:/*計算一棵樹中,距離最遠兩個節點之間的距離*/
/*具體演算法:每個節點有兩個域分別用來儲存它左子樹的最大高度lm和右子樹的最大高度rm
*將lm + rm與當前已知最遠的距離相比較,如果大於max,則更新max的值
*/int maxdist(tree root)
if(root->right != null)
root->rm = maxdist(root->right) + 1;
//如果以該節點為根的子樹中有最大的距離,那就更新最大距離
int sum = root->rm + root->lm;
if(sum > max)
return root->rm > root->lm ? root->rm : root->lm;
}
上面的**對每個節點只處理一次,所以時間複雜度是o(n),n是節點個數。 求二叉樹中節點的最大距離
遞迴求解,最大距離總是在一下兩種情況產生 情況1 最大路徑經過root 這個例子中,最長路徑經過root,其距離等於左子樹的高度 1 右子樹的高度 1 在這種情況下 如果只有左子樹,右子樹為空 最大距離 左子樹的高度 1 如果只有右子樹,左子樹為空 最大距離 右子樹的高度 1 如果既有右子樹,又有左...
求二叉樹中節點的最大距離
2010 10 26 16 03 37 分類 資料結構與演算法 標籤 proot 節點pleft pright nmaxleft 字型大小 大中小訂閱 如果我們把二叉樹看成乙個圖,父子節點之間的連線看成是雙向的,我們姑且定義 距離 為兩個節點之間邊的個數。寫乙個程式求一顆二叉樹中相距最遠的兩個節點之...
求二叉樹中節點的最大距離
如果我們把二叉樹看成乙個圖,父子之間的連線看成,姑且定義 距離 為兩個之間邊的個數。求一顆二叉樹中相距最遠兩個點之間的距離。struct node bittree int nmaxlen 0 void findmaxlen node proot if proot pleft null if proo...