华为OD -最小叶子节点(二叉树)

最小叶子节点

  1. 题目描述

二叉树也可以用数组来存储,

给定一个数组,树的根节点的值储存在下标1,

对于储存在下标n的节点,他的左子节点和右子节点分别储存在下标2*n和2*n+1,

并且我们用-1代表一个节点为空,

给定一个数组存储的二叉树,

试求从根节点到最小的叶子节点的路径,

路径由节点的值组成。

  1. 输入描述

输入一行为数组的内容,

数组的每个元素都是正整数,元素间用空格分割,

注意第一个元素即为根节点的值,

即数组的第n元素对应下标n,

下标0在树的表示中没有使用,所以我们省略了,

输入的树最多为7层。

  1. 输出描述

输出从根节点到最小叶子节点的路径上各个节点的值,

由空格分割,

用例保证最小叶子节点只有一个。

示例:

  1. 上代码

# !E:\pythonScript\venv python3
# -*- coding: utf-8 -*-
"""
Date: 2023/3/14
Time: 17:49
Author: kang
"""
import sys


def min_yz(tree_1): 
    min_val = sys.maxsize   # python可以处理或存储为变量的最大值: 9223372036854775807
    min_wz = 0
    split = ['0'] + tree_1
    for i in range(2, len(split)):
        tmp = int(split[i])
        if tmp != 0 and tmp != -1 and tmp < min_val and i * 2 >= len(split):
            min_val = tmp
            min_wz = i
    path = []
    back(split, min_wz, path)
    return path


def back(split, min_wz, path):
    path.append(split[min_wz])
    if min_wz == 1:
        return
    if min_wz % 2 == 0:
        back(split, min_wz // 2, path)
    else:
        back(split, (min_wz - 1) // 2, path)


def back_path(path):
    for i in range(len(path) - 1, -1, -1):
        print(path[i], end="")
        if i != 0:
            print(" ", end="")


if __name__ == "__main__":
    tree_2 = input().split()
    print(min_yz(tree_2))
    back_path(path=min_yz(tree_2))
  1. 解释一下:

min_yz的函数:其目的是在给定的树中找到最小的叶子节点,并返回从该叶子节点到根节点的路径。

  1. 首先,该函数定义了两个变量min_val和min_wz,分别用于存储最小叶子节点的值和位置。

  1. 将输入的字符串tree_1转换为一个节点值列表split,加“0”使得与二叉树下标相符从1开始

  1. 并在列表开头插入一个值为0的元素,作为树的根节点。

  1. 然后,该函数遍历split列表的所有非根节点,找到值最小的叶子节点,并记录其位置min_wz和值min_val。

tmp != 0:该条件用于判断当前节点是否为叶子节点,因为树的叶子节点的值不为0。
tmp != -1:该条件用于判断当前节点是否为一个空节点,因为空节点的值通常为-1(例如,二叉树中的空节点)。
tmp < min_val:该条件用于判断当前叶子节点的值是否比之前找到的最小叶子节点的值更小。
i * 2 >= len(split):该条件用于判断当前节点是否为叶子节点,因为根据二叉树的性质,如果一个节点的位置是i,它的左子节点的位置是2i,右子节点的位置是2i+1。因此,如果一个节点的位置是i,且它的左右子节点位置均超出了树的节点数量(即2i和2i+1都大于等于len(split)),那么它就是一个叶子节点。如果上述所有条件都满足,则说明当前节点是一个叶子节点,并且它的值比之前找到的最小叶子节点的值更小。因此,该节点的位置和值将被记录在min_wz和min_val变量中。

题目给定的列表创建二叉树为完全二叉树

对于任意一个完全二叉树来说,如果将含有的结点按照层次从左到右依次标号(如图 3a)),对于任意一个结点 i ,完全二叉树还有以下几个结论成立:

当 i>1 时,父亲结点为结点 [i/2] 。(i=1 时,表示的是根结点,无父亲结点)
如果 2*i>n(总结点的个数) ,则结点 i 肯定没有左孩子(为叶子结点);否则其左孩子是结点 2*i 。
如果 2*i+1>n ,则结点 i 肯定没有右孩子;否则右孩子是结点 2*i+1 。
  1. back的递归函数,用于构建从最小叶子节点到根节点的路径。

该函数接收三个参数:split列表、最小叶子节点的位置min_wz和一个空列表path,用于存储路径中的节点值。

具体来说,该函数首先将最小叶子节点的值添加到path列表中。然后,通过检查min_wz的值来确定当前节点的父节点的位置,以继续构建路径。

如果min_wz等于1,即最小叶子节点已经是根节点,则该函数返回并退出递归。

否则,如果min_wz是偶数,则它的父节点的位置是min_wz // 2,即min_wz除以2的整数部分。

如果min_wz是奇数,则它的父节点的位置是(min_wz - 1) // 2,即(min_wz - 1)除以2的整数部分。

在这两种情况下,该函数将继续以父节点的位置为参数调用back函数,直到达到根节点为止。

总之,该函数的作用是通过递归遍历树从最小叶子节点到根节点,以构建从最小叶子节点到根节点的路径,并将路径中的所有节点值添加到path列表中。

  1. back_path函数,简单的列表处理

这段代码是用来输出从最小叶子节点到根节点的路径的,它使用了一个for循环来遍历路径列表path中的所有节点。

具体来说,该循环从path列表的最后一个节点开始遍历,即从len(path)-1开始,每次递减1,直到遍历到第一个节点,即-1。在每个节点上,它使用print函数输出节点的值,并使用end参数将输出的字符串结尾设为空字符串,以避免在输出过程中出现换行符。

如果当前节点不是最后一个节点(即i不等于0),则在节点值之间输出一个空格。

end。。。😜

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值