二叉树中节点的最大的距离(编程之美3.8)
问题定义
把二叉树看成一个图,父子节点之间的连线看成是双向的,定义“距离”为两个节点之间的边数。例如下图中最大距离为红线的条数为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