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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux(9)find命令详解「建议收藏」

    linux(9)find命令详解「建议收藏」find命令格式:findpath-option[-print][-exec-okcommand]{}\;find命令的参数:path:要查找的目录路径。~表示$HO

    2022年7月29日
    7
  • ES6数组的各种方法「建议收藏」

    ES6数组的各种方法「建议收藏」1.ES6数组的各种方法2.forEach()函数①数组名.forEach(function(数组中一个元素的值){对这个值进行处理….})②数组名.forEach(test)test为方法名,不用加(),把函数引用传进去③利用函数引用这种方式的话,会自己把每个值传进去,不需要用()传进去3.map()方法①map()方…

    2022年6月13日
    30
  • 关于三极管的理解—根据IC符号简易迅速判断三极管导通情况

    关于三极管的理解—根据IC符号简易迅速判断三极管导通情况  很不幸,开始写博客的第一天就被师兄批评了。其实很对不起师兄,当年在大学学习模拟电路的时候我不太认真,那时候天天忙着和女朋友吃吃喝喝。。所以对于三极管的各种性质与基本运用场景缺乏较深的理解,仅仅只是知道导通、截止等几种判断方式而已。今天在设计电路时涉及到了运用三极管驱动光耦器件,以及通过三极管来驱动蜂鸣器等操作,在三极管的选材和设计上出现了低级的失误。检讨完毕后,翻出当年的模电书,配…

    2022年6月17日
    43
  • Jlink或者stlink用于SWD接口下载程序「建议收藏」

    Jlink或者stlink用于SWD接口下载程序「建议收藏」最近要使用stm32f103c8t6最小系统板,直接ISP串口下载程序太麻烦,就想着使用swd接口来调试。结果:通过SWD接口下载程序成功,但调试失败,还不知原因,会的的人麻烦交流一下。SWD接口:3.3VDIO(数据)CLK(时钟)GND1.首先声明jlink和stlink都有jtag和swd调试功能。jlink接口如下:如图,我使用的就是VCC…

    2022年4月25日
    96
  • html网页动态日历代码_春节倒计时源码

    html网页动态日历代码_春节倒计时源码点击文章下面超链接,即可免费下载,源码以及文件素材,无需积分,关注后即可下载记得关注,只有关注后才可以下载!!!效果图:钟表以及时间文字显示会自动根据打开网页的时间,显示时间;无需自己修改,弹幕和文字皆可以修改;背景是渐变色彩,可根据自己的需要在源码中修改即可,除了主要功能是HTML意外,还有CSS、JS等源码,就算没有编程工具,电脑没有任何编程配置,只需要打开文件,鼠标双击运行index即可,会自动跳到系统默认浏览器内,就算毫无编程基础、英语小白页可以娱乐;本源码意在学习与娱乐,未经授权!!禁止商用

    2022年10月19日
    2
  • MapReduce编程模型详解

    MapReduce编程模型详解1.1MapReduce是什么  HadoopMapReduce是一个软件框架,基于该框架能够容易地编写应用程序,这些应用程序能够运行在由上千个商用机器组成的大集群上,并以一种可靠的,具有容错能力的方式并行地处理上TB级别的海量数据集。这个定义里面有着这些关键词,一是软件框架,二是并行处理,三是可靠且容错,四是大规模集群,五是海量数据集。1.2MapReduce做什么…

    2022年6月18日
    29

发表回复

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

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