PTA 二叉树叶结点值和最大层(C 语言)

已知一棵非空二叉树结点的数据域为不等于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;
}

 如果对过程还是不够清晰可以画递归图理解。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值