問題定義
把二叉樹看成一個圖,父子節點之間的連線看成是雙向的,定義“距離”為兩個節點之間的邊數。例如下圖中最大距離為紅線的條數為6.
分析
定義:過以節點x作為根節點的子樹中,節點間的最大距離為Dis(x)。
上圖,左圖中Dis(根節點)最大,右圖中Dis(根節點->left)最大。從上邊可以看出每個節點都可能成為最大距離根節點的潛質。
因此可以求出每個Dis(節點),從中得出最大值即為整個二叉樹的根節點最大值。
在求過點x的最大距離時,最大距離的兩個點有可能出現在三種情況下
- 左子樹
- 右子樹
- 過節點x
經分析得出以下特點
- 以上三種情況最終必定一葉子結束
- 在第三種情況下必然是左子樹高度 與 右子樹高度 之和(只有這樣,才可能取得最大值)
經過以上分析即可得出遞推式
Dis(x) = max(Dis(x->left), Dis(x->right), height(x->left)+height(x->right))
參考代碼
int treeDistance(BiTree root) { if(root == NULL) return 0; else if(root->left == NULL && root->right == NULL) return 0; int dis = max(height(root->left) + height(root->right), treeDistance(root->left), treeDistance(root->right)); if(maxDis < dis) maxDis = dis; return dis; }
這里用了一個技巧:maxDis是個全局變量,遞歸一次根節點會遍歷到每個節點,在這期間於maxDis比較,從而得出了最大值,而不需要額外的空間。
完整運行代碼

#include<iostream> using namespace std; typedef struct BiTNode { BiTNode *left; BiTNode *right; }BiTNode, *BiTree; int maxDis = 0; void createTree(BiTree &root) { BiTree left1 = new(BiTNode); BiTree right1 = new(BiTNode); left1->left = NULL; left1->right = NULL; right1->left = NULL; right1->right = NULL; root->left = left1; root->right = right1; BiTree left2 = new(BiTNode); left2->left = NULL; left2->right = NULL; BiTree right2 = new(BiTNode); right2->left = NULL; right2->right = NULL; left1->left = left2; left1->right = right2; BiTree left3 = new(BiTNode); left3->left = NULL; left3->right = NULL; BiTree right3 = new(BiTNode); right3->left = NULL; right3->right = NULL; left2->left = left3; left2->right = right3; } void deleteTree(BiTree root) { if(root) { deleteTree(root->left); deleteTree(root->right); delete(root); root = NULL; } } int height(BiTree root) { if(root == NULL) return 0; else return height(root->left) > height(root->right) ? height(root->left) + 1 : height(root->right) + 1; } int max(int a, int b, int c) { int tmp = a > b ? a : b; return tmp > c ? tmp : c; } int treeDistance(BiTree root) { if(root == NULL) return 0; else if(root->left == NULL && root->right == NULL) return 0; int dis = max(height(root->left) + height(root->right), treeDistance(root->left), treeDistance(root->right)); if(maxDis < dis) maxDis = dis; return dis; } int main() { BiTree root = new(BiTNode); root->right = root->left = NULL; createTree(root); cout << "height:" << height(root) << endl; cout << "treeDistance:" << treeDistance(root) << endl; cout << "_____________________" << endl; deleteTree(root); }
結果
4