求解 二叉树用数组来存储

题目出处:

————————————————
版权声明:本文为CSDN博主「羊族的希望」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41010318/article/details/120731302

二叉树也可以用数组来存储
给定一个数组
树的根节点的值储存在下标1
对于储存在下标n的节点,
他的左子节点和右子节点分别储存在下标2*n和2*n+1
并且我们用-1代表一个节点为空
给定一个数组存储的二叉树
试求从根节点到最小的叶子节点的路径
路径由节点的值组成

输入描述
输入一行为数组的内容
数组的每个元素都是正整数,元素间用空格分割
注意第一个元素即为根节点的值
即数组的第n元素对应下标n
下标0在树的表示中没有使用
所以我们省略了
输入的树最多为7层

输出描述
 输出从根节点到最小叶子节点的路径上各个节点的值
 由空格分割
 用例保证最小叶子节点只有一个

 例子
  输入
  3 5 7 -1 -1 2 4
  输出
   3 7 2

  例子
   输入
  5 9 8 -1 -1 7 -1 -1 -1 -1 -1 6
   输出
  5 8 7 6

===============================================================

======================忧伤的分割线===============================

解题思路:

求出所有叶子节点中最小值,然后根据叶子结点下标即可推出父节点直到根节点

叶子结点条件:a[i] != -1 && a[2 * i] = -1 && a[2 * i + 1] = -1

                 或者 a[i] !=  -1 && 2 * i 超出总的节点数,比如用例1中节点2和节点4已经是叶子节点

找出最小叶子结点下标a[6] = 2  父节点a[6/2]=7 父节点(根节点)a[6/2/2] = 3

结果3 7 2

source code:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        int i;
        int min_pos = 0;
        int min = 0x0fffffff;
        int count = 1; /* 根节点从下标1开始 */
        int a[128] = {0};
        int res[128] = {0}; /* 记录路径 */
        printf("input int array:\n");
        while (scanf("%d", &a[count]) != EOF) {
                count++;
        }

    /* 调试 */
        printf("count = %d\n", count);
        for (i = 1; i < count; i++) {
                printf("%d ", a[i]);
        }
        printf("\n");

        for (i = 1; i < count; i++) {
        /* 找叶子节点:左右子节点为-1则是叶子结点,或者数组最后元素无子节点即是叶子结点 */
                if ((a[i] != -1) && ((a[2 * i] == -1 && a[2 * i + 1] == -1) ||
                        (2 * i > count - 1))) {
            /* 打印找到的叶子结点 */
                        printf("a[%d]:%d\n", i, a[i]);
                        if (a[i] < min) {
                                min = a[i];
                                min_pos = i;
                        }
                }
        }
        count = 0;
        while (min_pos != 0) {
                res[count] = a[min_pos];
                count++;
                min_pos /= 2;
        }
        for (i = count - 1; i >= 0; i--) {
                printf("%d ", res[i]);
        }
        printf("\n");
        return 0;
}
 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值