python实现二叉树层序遍历(逐层打印二叉树)「建议收藏」

python实现二叉树层序遍历(逐层打印二叉树)「建议收藏」题目要求给定一个二叉树,要求从上往下逐层打印该二叉树节点的值,每层从左往右打印。解题思路——广度优先遍历实际上就是广度优先遍历,借助一个队列(这里用数组代替)就可以实现:1、先将root节点加入队列2、队列不为空时取队列首节点3、打印节点的值,然后将该节点的左、右子节点先后加入队尾(核心步骤,广度优先体现在这)4、回到2,直到队列为空该方法对满二叉树和非满二叉树都符合题目要求。…

大家好,又见面了,我是你们的朋友全栈君。

题目要求

给定一个二叉树,要求从上往下逐层打印该二叉树节点的值,每层从左往右打印。

解题思路——广度优先遍历

实际上就是广度优先遍历, 借助一个队列(这里用数组代替)就可以实现:
1、先将root节点加入队列
2、队列不为空时取队列首节点
3、打印节点的值,然后将该节点的左、右子节点先后加入队尾(核心步骤,广度优先体现在这)
4、回到2,直到队列为空

该方法对满二叉树非满二叉树都符合题目要求。

代码实现

1. 先定义二叉树的类

class TreeNode:
    def __init__(self, value):
        self.val = value
        self.left = None
        self.right = None

2. 先从打印一行开始

一步一步来,我们先将所有节点的值按层序打印在一行,即每层之间不换行。后面的函数都是基于这个母版进行的改进。

def print_in_one_line(root):
    ''' 1. 简单版: 打印在一行内,不换行 '''
    if not root:
        return 
    queue = []
    queue.append(root)
    while len(queue) > 0:
        node = queue.pop(0)
        print(node.val, end = " ") # end属性默认为“\n”,所以print()函数默认会换行。此处设为空格“ ”,防止自动换行
        if node.left:
            queue.append(node.left) # 将本节点的左子节点入队
        if node.right:
            queue.append(node.right) # 将本节点的右子节点入队

3. 逐行打印——初级

在node入队时候就加入行号信息,然后判断line与current_line是否相等来控制换行,即当line与current_line不相等时换到下一行。

缺点

  1. 需要辅助结构line/current_line
  2. node入队时加入的行号信息增加了空间的开销。
def print_by_layer_1(root):
    ''' 2. 逐行打印——初级版: 用line/current_line 控制换行,在入队时候即加入行号信息 '''
    if not root:
        return 
    queue = [] #
    current_line = 0
    queue.append([current_line, root])
    while len(queue) > 0:
        line, node = queue.pop(0)
        # 核心判断:是否换行
        if line != current_line:
            print()  # 不同时换行,print()函数默认end=“\n”
            current_line = line
        print(node.val, end = " ")
        if node.left:
            queue.append([line+1, node.left])  # 将本节点的行号和左子节点入队
        if node.right:
            queue.append([line+1, node.right]) # 将本节点的行号和右子节点入队

4. 逐行打印——高阶

不需要line/current_line来判断,而是在入队时候就加入换行信息,即在每层第一个节点的子左节点入队之前就加入一个换行标记,该换行标记可以自定义,任何非TreeNode对象就行,这里我用字符“r”代替。
注意:控制好边界条件,防止陷入死循环,别问我是怎么知道的。。。

def print_by_layer_2(root):
    ''' 3. 终极版 无line/current_line,在入队时候加入换行标记信息,注意边界条件,防止陷入死循环 '''
    if not root:
        return 
    queue = ["r"] # 一开始塞入一个换行标记,作为队首,任何非TreeNode对象都行。
    queue.append(root)
    while len(queue) > 0:
        node = queue.pop(0)
        if isinstance(node,TreeNode):
            print(node.val, end = " ")
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        else:
            # 边界条件
            if len(queue) > 0:
                queue.append("r") # 对尾添加换行标记
                print()  # 换行

结果验证

好了,接下来看一下函数的表现,我们写了一个主函数:


if __name__ == "__main__":

    # 新建节点 
    node1 = TreeNode(1)
    node2 = TreeNode(2)
    node3 = TreeNode(3)
    node4 = TreeNode(4)
    node5 = TreeNode(5)
    node6 = TreeNode(6)
    node7 = TreeNode(7)
    node8 = TreeNode(8)
    node9 = TreeNode(9)
    node10 = TreeNode(10)
    node11 = TreeNode(11)

    # 构建二叉树
    node1.left, node1.right = node2, node3
    node2.left, node2.right = node4, node5
    node3.left, node3.right = node6, node7
    node4.left, node4.right = node8, node9
    node5.left, node5.right = node10, node11

    # 指定 node1 为root节点
    root = node1

    # 打印
    print("\nprint in one line:")
    print_in_one_line(root)

    print("\n\nprint by layer 1:")
    print_by_layer_1(root)
    
    print("\n\nprint by layer 2:")
    print_by_layer_2(root)

定义的二叉树:
在这里插入图片描述
打印结果:
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143485.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • electron preload 提前_electron vue3

    electron preload 提前_electron vue3背景最近手头的electron项目需要做一个报告导出的功能,导出时要弹出个页面,可让用户自行补全相应的字段。由于公司已有现成的笔录工具,现直接将其集成进来,用webview直接展示其笔录页面,将已有的值传给笔录。webview简介electron的webview标签时基于Chromiumwebview,由于Chromium的架构变化巨大,会影响electronwebview的稳定性,包括呈现、导航和事件路由。所以electron团队不建议使用webview标

    2025年7月22日
    3
  • linux系统查看网卡命令_linux如何配置网卡

    linux系统查看网卡命令_linux如何配置网卡rhel内核版本号信息:[root@hvrhub~]#uname-aLinuxhvrhub2.6.18-308.el5#1SMPFriJan2717:17:51EST2012x86_64x86_64x86_64GNU/Linux查看网卡的驱动。制造商等信息:[root@hvrhub~]#kudzu–probe–class=network-class:…

    2022年10月19日
    2
  • 数据结构与算法Python_数据结构与算法python语言实现

    数据结构与算法Python_数据结构与算法python语言实现我们已经知道算法是具有有限步骤的过程,其最终的目的是为了解决问题,而根据我们的经验,同一个问题的解决方法通常并非唯一。这就产生一个有趣的问题:如何对比用于解决同一问题的不同算法?为了以合理的方式提高程序效率,我们应该知道如何准确评估一个算法的性能。本节学习首先介绍算法分析的重要性,并讲解了分析算法的时间复杂度和空间复杂度分析方法,最后介绍了Python列表和字典常见操作的时间复杂度。

    2022年9月27日
    4
  • 火眼金睛审核 一键轻松处理[通俗易懂]

    火眼金睛审核 一键轻松处理——学籍助手简介学籍助手是专为河北省义务教育学籍管理系统区县端开发的一款辅助工具(图)。该工具不影响原系统正常使用,只是扩充了一些实用功能,只是让学籍管理变得异常轻松简单(如您不是区县学籍管理员,请勿下载)。学籍助手具有严格的入库审核、强大的批量处理和轻松的数据对接功能,犹如为原学籍管理系统赋予一双慧眼、插上一对翅膀,从容处理繁杂的学籍变…

    2022年4月13日
    50
  • 随机森林算法原理简要总结怎么写_旋转森林算法

    随机森林算法原理简要总结怎么写_旋转森林算法①RandomForest随机森林算法原理:即bagging法+CART算法生成决策树的结合。RF=bagging+fully-grownCARTdecisiontree②bagging法的核心:bootstrap在原始数据集D中选择若干个子数据集Dt,将子数据集单个单个进行决策树生成。③随机森林的优点:可并行化计算(子集的训练相互独立),效率高继承了CART算法的优点(使用Gini系数选择最优特征及切分点)减小了完全生成树的弊端(因为完全生成树过于复杂,Ein小但E

    2025年7月14日
    3
  • 频谱仪的更改ip_通过局域网(LAN)读取频谱分析仪图像的方法

    频谱仪的更改ip_通过局域网(LAN)读取频谱分析仪图像的方法频谱分析仪在WiFi产品的开发过程中是一种必不可少的有力工具,是射频工程师的得力助手。通常,工程师使用软盘去读取频谱分析仪的图像,这不仅复杂而且现在软盘也不容易买到,即使买到也未必能用,在这里我给出使用局域网(LAN)访问频谱分析仪图像的方法。今天,我发现了一个不用软盘也能存取频谱分析仪上的图像的方法,我从一开始就觉得,既然频谱分析仪后面留有GPIB和LAN接口,就一定能通过GPIB或者LAN…

    2022年8月11日
    17

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号