Python面试宝典第8题:二叉树遍历

题目

        给定一棵二叉树的根节点 root ,返回它节点值的前序遍历。

        示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]

        示例 2:

输入:root = []
输出:[]

        示例 3:

输入:root = [1]
输出:[1]

基础知识

        二叉树属于一种常用的数据结构,是一个由零个或多个节点组成的层次结构。二叉树具有以下特征:

        1、每个节点最多有两个子节点,分别称为左子节点和右子节点。

        2、根节点位于树的最顶端,没有父节点。

        3、叶子节点没有子节点。

        4、非叶子节点至少有一个子节点。

        前序遍历是二叉树遍历的一种方式,其顺序遵循“根节点 -> 左子树 -> 右子树”的原则。具体步骤如下:

        1、访问当前节点:首先处理当前节点(打印节点值,或进行其他操作)。

        2、递归地遍历左子树:然后对当前节点的左子树进行前序遍历。

        3、递归地遍历右子树:最后对当前节点的右子树进行前序遍历。

        假如我们有以下的二叉树,则其前序遍历的顺序为:1 -> 2 -> 4 -> 5 -> 3。

    1
   / \
  2   3
 / \
4   5

递归法

        对于给定的二叉树,我们可以通过递归的方式来实现前序遍历。下面我们给出了用递归法解题的示例代码,具体的解题步骤如下。

        1、binary_tree_traversal_recursive 函数接收一个 TreeNode 类型的参数 root,它代表二叉树的根节点。函数内部定义了另一个名为 dfs 的辅助函数,该函数负责实际的递归遍历工作。

        2、在 dfs 函数中,我们先访问当前节点,然后递归访问左子树,最后递归访问右子树。

        3、遍历完成后,所有节点都已访问,dfs 函数逐级返回,最终 binary_tree_traversal_recursive 函数返回结果列表 result。

from typing import List

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

def binary_tree_traversal_recursive(root: TreeNode) -> List[int]:
    result = []

    def dfs(node):
        if node is None:
            return
        
        # 访问当前节点
        result.append(node.val)
        # 递归访问左子树
        dfs(node.left)
        # 递归访问右子树
        dfs(node.right)

    dfs(root)
    return result

right = TreeNode(2)
root = TreeNode(1, None, right)
right.left = TreeNode(3)
result = binary_tree_traversal_recursive(root)
print(result)

迭代法

        迭代法实现二叉树的前序遍历,关键在于利用栈来模拟递归的过程,确保节点的访问顺序符合“根节点 -> 左子树 -> 右子树”的规则。使用迭代法求解本题的主要步骤如下。

        1、初始化。创建一个栈,并将根节点压入栈中。同时,创建一个结果列表用于存放遍历结果。

        2、循环处理。当栈不为空时,执行以下操作:

        (1)弹出栈顶元素。将栈顶元素弹出,并将其值添加到结果列表中,这是因为前序遍历先访问根节点。

        (2)处理右子树。如果当前节点有右子节点,将右子节点压入栈中。这是因为,右子节点应当在其左子树访问完后再访问,故右子节点应最后处理。

        (3)处理左子树。如果当前节点有左子节点,将左子节点压入栈中。这是因为,左子节点应在当前节点的右子节点之前访问。

        3、结束条件。当栈为空时,所有节点都被访问过,遍历结束。

        根据上面的算法步骤,我们可以得出下面的示例代码。

from typing import List

def binary_tree_traversal_iteration(root: TreeNode) -> List[int]:
    if not root:
        return []
    
    stack, result = [root, ], []
    while stack:
        # 弹出栈顶元素并访问
        node = stack.pop()
        if node:
            # 访问栈顶节点
            result.append(node.val)
            
            # 栈顶元素出栈后,先压右子节点,保证右子节点最后访问
            if node.right:
                stack.append(node.right)

            # 然后压左子节点
            if node.left:
                stack.append(node.left)
    
    return result

right = TreeNode(2)
root = TreeNode(1, None, right)
right.left = TreeNode(3)
result = binary_tree_traversal_iteration(root)
print(result)

总结

        递归法的时间复杂度为O(n),每个节点被访问一次。空间复杂度最好情况下为O(log n)(此时为平衡树),最坏情况下为O(n)(此时为高度为n的斜树)。递归法的实现直观反映了前序遍历的逻辑,即“根-左-右”,但存在栈溢出、空间复杂度较高等缺点。

        迭代法的时间复杂度也为O(n),每个节点被访问一次。空间复杂度为O(h),其中h是树的高度。对于平衡树来说为O(log n),最坏情况下(高度为n的斜树)为O(n)。相较于递归法,迭代法使用显式栈管理,空间复杂度更加可控。此外,迭代法没有递归调用栈的限制,适用于处理大规模或深度极大的二叉树。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/788255.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器人伦理分析:从扫地机器人到智能伙伴

我发过一个泡泡:机器人和扫地机器人。 意犹未尽,我觉得这是一个值得讨论下去的话题。或者是未来话题 在科技迅猛发展的今天,机器人已经从简单的执行工具演变为能够执行复杂任务的智能实体。特别是在家庭环境中,扫地机器人已经成为…

Python酷库之旅-第三方库Pandas(012)

目录 一、用法精讲 28、pandas.HDFStore.keys函数 28-1、语法 28-2、参数 28-3、功能 28-4、返回值 28-5、说明 28-6、用法 28-6-1、数据准备 28-6-2、代码示例 28-6-3、结果输出 29、pandas.HDFStore.groups函数 29-1、语法 29-2、参数 29-3、功能 29-4、返回…

14-57 剑和诗人31 - LLM/SLM 中的高级 RAG

​​​ 首先确定几个缩写的意思 SLM 小模型 LLM 大模型 检索增强生成 (RAG) 已成为一种增强语言模型能力的强大技术。通过检索和调整外部知识,RAG 可让模型生成更准确、更相关、更全面的文本。 RAG 架构主要有三种类型:简单型、模块化和高级 RAG&…

嵌入式通信协议全解析:SPI、I²C、UART详解(附带面试题)

目录 一、什么是通信 二、 通信的分类 同步通信(Synchronous Communication) 异步通信(Asynchronous Communication) 不同协议标准区分图: UART UART的特点: UART的通信过程: UART的配置…

设计模式探索:装饰器模式

1. 装饰器模式定义 装饰器模式(Decorator Pattern) 装饰器模式是一种结构型设计模式,允许向一个对象动态添加行为。在不改变类的接口的情况下,装饰器模式在原始类上增加额外的职责,并且支持多个装饰器嵌套使用。 装…

使用树莓派进行python开发,控制电机的参考资料

网站连接:https://www.cnblogs.com/kevenduan?page1 1、简洁的过程步骤, 2、有代码示例, 3、有注意事项,

数据结构--二叉树相关习题5(判断二叉树是否是完全二叉树 )

1.判断二叉树是否是完全二叉树 辨别: 不能使用递归或者算节点个数和高度来判断。 满二叉树可以用高度和节点来判断,因为是完整的。 但是完全二叉树前面是满的,但是最后一层是从左到右连续这种 如果仍然用这种方法的话,如下图…

零信任网络安全

随着数字化转型的发生,网络边界也在不断被重新定义,因此,组织必须使用新的安全方法重新定义其防御策略。 零信任是一种基于“永不信任,永远验证”原则的安全方法,它强调无论在公司内部或外部,任何用户、设…

电脑文件夹怎么设置密码?让你的文件更安全!

在日常使用电脑的过程中,我们常常会有一些需要保护的个人文件或资料。为了防止这些文件被他人未经授权访问,对重要文件夹设置密码是一种有效的保护措施,可是电脑文件夹怎么设置密码呢?本文将介绍2种简单有效的方法帮助您为电脑文件…

数据结构基础--------【二叉树题型】

1、前提(待补充) 1.**DFS(Depth First Search)😗*递归法得到最终的数组(深度优先算法) 其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,如果遇到死路就往回退,回退过程中如果遇…

简易限流实现

需求描述 写一个1秒两个的限流工具类,2r/s 使用semaphore 代码实现-类似令牌桶算法 public class LimitHelper {private int maxLimit;private Semaphore semaphore;private int timeoutSeconds;public LimitHelper(int maxLimit, int timeoutSeconds) {this.max…

OpenAI与Thrive Global推出Thrive AI Health:AI驱动的健康教练应用

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

MMGPL: 多模态医学数据分析与图提示学习| 文献速递-基于深度学习的多模态数据分析与生存分析

Title 题目 MMGPL: Multimodal Medical Data Analysis with Graph Prompt Learning MMGPL: 多模态医学数据分析与图提示学习 01 文献速递介绍 神经学障碍,包括自闭症谱系障碍(ASD)(Lord等,2018年)和阿…

虚拟内存【Linux】

虚拟内存 为什么需要虚拟内存Linux虚拟内存的结构32位系统下的虚拟地址空间64位系统下的虚拟地址空间页表多级页表TLB 流程虚拟内存的作用 为什么需要虚拟内存 为了在进行多进程编码进行内存访问的时候保持内存的隔离性,数据安全性,所以出现了虚拟内存。…

PPI(每英寸像素数)、DPI(每英寸点数)和Pixel(像素)的区别和联系?

一、定义 PPI、DPI和Pixel是图像处理、打印和显示领域中常用的三个概念,它们之间既有区别又有联系。以下是对这三个概念进行分别讲解: 1. PPI(Pixels Per Inch)-即每英寸像素数,是图像分辨率的一种表示方…

(补充):java各种进制和文本、图像、音频在计算机中的存储方式

文章目录 前言一、进制1 逢几进一2 常见进制在java中的表示3 进制中的转换(1)任意进制转十进制(2)十进制转其他进制二、计算机中的存储1 计算机的存储规则(文本数据)(1)ASCII码表(2)编码规则的发展演化2 计算机的存储规则(图片数据)(1)分辨率、像素(2)黑白图与灰度…

科技日报社激发数据要素价值,树立媒体行业数字化转型标杆

更多案例研究与行业报告,请前往爱分析官网 媒体行业企事业单位在数据要素领域得天独厚,日积月累的新闻报道、媒资素材、读者反馈和市场研究,沉淀出属于它们的“数据金矿”。 但是,多数相关单位尚未重视和发挥数据要素价值&#…

LLM应用构建前的非结构化数据处理(三)文档表格的提取

1.学习内容 本节次学习内容来自于吴恩达老师的Preprocessing Unstructured Data for LLM Applications课程,因涉及到非结构化数据的相关处理,遂做学习整理。 本节主要学习pdf中的表格数据处理 2.环境准备 和之前一样,可以参考LLM应用构建前…

车载聚合路由器应用场景分析

乾元通QYT-X1z车载式1U多卡聚合路由器,支持最多8路聚合,无论是应急救援,还是车载交通,任何宽带服务商无法覆盖的区域,聚合路由器可提供现场需要的稳定、流畅、安全的视频传输网络,聚合路由器可无缝接入应急…

Flutter-实现物理小球碰撞效果

效果 引言 在Flutter应用中实现物理动画效果,可以大大提升用户体验。本文将详细介绍如何在Flutter中创建一个模拟物理碰撞的动画小球界面,主要代码实现基于集成sensors_plus插件来获取设备的加速度传感器数据。 准备工作 在开始之前,请确保在pubspec.yaml文件中添加senso…