递归求解,最大距离总是在一下两种情况产生
情况1: 最大路径经过root
这个例子中,最长路径经过root, 其距离等于左子树的高度 + 1 + 右子树的高度 + 1
在这种情况下:
如果只有左子树,右子树为空
最大距离 = (左子树的高度 + 1)
如果只有右子树,左子树为空
最大距离 = (右子树的高度 + 1)
如果既有右子树,又有左子树
最大距离 = (左子树的高度 + 1) + (右子树的高度 + 1)
情况2: 最大路径不经过root
这个例子中,最长路径不经过root, 最长路径全部在右子树中。
在这种情况下:
最大距离 = max{左子树的最大距离, 右子树的最大距离}
综合以上两种情况:
最大距离 = max{情况1的最大距离, 情况2的最大距离}
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX(a,b) ((a) > (b) ? (a) : (b))
typedef struct node_t{
int data;
struct node_t *left, *right;
}node_t;
/* 先序创建二叉树 */
node_t *create_tree()
{
int data;
node_t *node;
scanf("%d", &data);
if (data == -1) return NULL;
node = (node_t *)malloc(sizeof(node_t));
node->data = data;
node->left = create_tree();
node->right = create_tree();
return node;
}
/* 递归求树的最大距离和高度 */
int find_max_dist(node_t *root, int *height)
{
int lh, rh, left_dist, right_dist, max_dist;
if (root == NULL) {
*height = -1;
return 0;
}
/* 情况2,最大路径不经过root,最大路径在子树中产生 */
left_dist = find_max_dist(root->left, height);
lh = *height;
right_dist = find_max_dist(root->right, height);
rh = *height;
*height = MAX(lh, rh) + 1;
max_dist = MAX(left_dist, right_dist);
/* 情况1,经过root,最大距离等于左右子树的高度加上2,
* 递归的过程中,顺便求出根节点的高度 */
int dist = 0;
if (root->left != NULL) {
dist = lh + 1;
}
if (root->right != NULL) {
dist += rh + 1;
}
/* 最大距离在情况1和情况2中产生 */
max_dist = MAX(dist, max_dist);
return max_dist;
}
int main()
{
node_t *root;
int height;
root = create_tree();
printf("最大路径 = %d\n", find_max_dist(root, &height));
printf("树的高度 = %d\n", height);
return 0;
}
测试输入
输入: 1 2 4 -1 -1 5 -1 -1 3 -1 -1
生成的二叉树为:
求出最大距离等于 3