已知一棵非空二叉树结点的数据域为不等于0的整数,请编写程序找出该二叉树中叶结点数据值之和最大的层。
输入格式:
输入为一组用空格间隔的整数,个数不超过100个,表示带空指针信息的二叉树先根序列。
输出格式:
输出为一个整数,表示叶结点数据值之和最大的层,如果存在多个满足条件的层,则输出最下面一层。
输入样例1:
1 2 0 0 3 0 0
输出样例1:
1
输入样例2:
1 -2 0 0 3 -1 0 0 -1 0 0
输出样例2:
2
思路:
分而治之,拿一棵树举例子, 从左子树开始,通过递归一层一层下去,到叶子节点后记录该值,
再递归右子树,到叶子节点后同样将该值记录,最后对比左右子树的高度值和叶子节点的值来判断下一步如何赋值。
拿样例二举例子
左子树递归
可知左子树高度为一,叶结点值和为-2
右子树递归
此时可以看到在 3 为根节点时, 左右子树高度相等, -1 相加为 -2,着该层最大为 -2
最后可得 :左子树高度为 1 叶结点值和为 -2
右子树高度为 2 叶结点值和为 -2
此时由题意得应该取高度最大得层数 得为2
#include<stdio.h>
#include<stdlib.h>
//建一个二叉树结构体
typedef struct tree
{
int data;
struct tree* left;
struct tree* right;
}Tree;
//建造需要对比树的高度和叶子和的一个结构体
typedef struct max {
int sum;
int height;
}Max;
//通过前序遍历的方式建树
Tree* Preface(Tree* t) {
int num;
scanf("%d", &num);
//num 为 0 时不需要为他建节点
if (!t && num) {
t = (Tree*)malloc(sizeof(Tree));
t->data = num;
t->left = NULL;
t->right = NULL;
t->left = Preface(t->left);
t->right = Preface(t->right);
}
return t;
}
Max findMax(Max leftMax, Max rightMax, Max m) {
//左子树的高大于右子树的高
//意味着左右树的叶子节点此时都不在同一层直接比较大小
if (leftMax.height > rightMax.height) {
if (leftMax.sum > rightMax.sum) {
m.height = leftMax.height;
m.sum = leftMax.sum;
}
else if (leftMax.sum < rightMax.sum) {
m.height = rightMax.height;
m.sum = rightMax.sum;
}
else {//取高度最大的一层
m.height = leftMax.height;
m.sum = leftMax.sum;
}
}//与上面同理
else if (leftMax.height < rightMax.height) {
if (leftMax.sum > rightMax.sum) {
m.height = leftMax.height;
m.sum = leftMax.sum;
}
else if (leftMax.sum < rightMax.sum) {
m.height = rightMax.height;
m.sum = rightMax.sum;
}
else {
m.height = rightMax.height;
m.sum = rightMax.sum;
}
}//此时左右子树高度相同 意味着叶子节点都在同一层 由题意知同一层该相加
else {
m.height = leftMax.height;
m.sum = leftMax.sum + rightMax.sum;
}
//返回更新后的最大值
return m;
}
//找叶子节点最大值最大的层之和
Max leafNodesAnd(Tree* t, Max m) {
//到下一层后树的高度加一
m.height++;
//判断该节点是否为空
if (!t) {
return m;
}
else if (!t->left && !t->right) {
//判断该节点是否为叶子节点
m.sum += t->data;
return m;
}
Max leftMax = leafNodesAnd(t->left, m);//在左子树找到叶子节点最大值最大的层之和
Max rightMax = leafNodesAnd(t->right, m);//在右子树找到叶子节点最大值最大的层之和
//对左右子树中叶子节点最大值最大的层之和进行筛选
m = findMax(leftMax, rightMax, m);
return m;
}
int main() {
Tree* t = NULL;
t = Preface(t);
Max m = { 0,0 };
//找叶子节点最大值最大的层之和
m = leafNodesAnd(t, m);
//题目所定的高度与我们平时理解不同需要 减一 得到答案
printf("%d", m.height - 1);
return 0;
}
如果对过程还是不够清晰可以画递归图理解。