代码随想录算法训练营第13天|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法、102.二叉树的层序遍历

打卡Day13

  • 1.理论基础
  • 2.二叉树的递归遍历
  • 3.二叉树的迭代遍历
  • 3.二叉树的统一迭代法
  • 4.102.二叉树的层序遍历
    • 扩展
      • 107. 二叉树的层序遍历 II
      • 199.二叉树的右视图
      • 637.二叉树的层平均值
      • 429.N叉树的层序遍历
      • 515.在每个树行中找最大值
      • 116.填充每个节点的下一个右侧节点指针
      • 117. 填充每个节点的下一个右侧节点指针 II
      • 104. 二叉树的最大深度
      • #111.二叉树的最小深度

1.理论基础

文档讲解: 代码随想录

解题过程二叉树有两种主要形式:满二叉树和完全二叉树。
(1)满二叉树:一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上。深度为 k 的满二叉树有 2^k - 1 个节点。

在这里插入图片描述
(2)完全二叉树:除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面的节点都集中在该层最左边的若干位置。若最底层为第 h(h >= 1) 层,则该层包含 1 ~ 2^(h -1) 。

在这里插入图片描述
之前优先级队列其实是一个堆,堆是一颗完全二叉树,同时保证父子节点的顺序关系。

二叉搜索树:是一个有序树。
平衡二叉搜索树:是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

二叉树的定义:


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

2.二叉树的递归遍历

文档讲解: 代码随想录

递归算法的三要素:
(1)确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数,并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
(2)确定终止条件:如果递归没有终止,操作系统的内存站必然会溢出。运行递归算法遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对。
(3)确定单层递归的逻辑:确定每一层递归需要处理的信息,在这里也就会重复调用自己来实现递归的过程。

以前序遍历为例:
(1)确定递归函数的参数和返回值:参数为当前树节点,返回值为空。我本来以为需要返回节点的数据,但在函数的内部直接将数据加入到列表中。
(2)终止条件:当遍历的节点为空,直接return。
(3)确定单层递归的逻辑:先取中节点的数值,再取左节点,最后右节点。

题目链接:前序遍历

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """

        res = []
        
        def dfs(node):
            if node is None:
                return

            res.append(node.val)
            dfs(node.left)
            dfs(node.right)

        dfs(root)
        return res       

题目链接:后序遍历

class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []

        def dfs(node):
            if node is None:
                return
            
            dfs(node.left)
            dfs(node.right)
            res.append(node.val)
        
        dfs(root)
        return res

题目链接:中序遍历

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        
        res = []

        def dfs(node):
            if node is None:
                return 
            dfs(node.left)
            res.append(node.val)
            dfs(node.right)
        
        dfs(root)
        return res

3.二叉树的迭代遍历

文档讲解: 代码随想录

题目链接:前序遍历

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        
        #跟节点先入栈
        stack = [root]
        res = []

        while stack:
            node = stack.pop()
            #处理中节点
            res.append(node.val)
            #右孩子先入栈
            if node.right:
                stack.append(node.right)
            #左孩子入栈
            if node.left:
                stack.append(node.left)
        
        return res

题目链接:后序遍历

class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        
        stack = [root]
        res = []

        while stack:
            node = stack.pop()
            res.append(node.val)
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
        
        return res[::-1]

题目链接:中序遍历

在中序遍历中,处理元素和访问元素的顺序不一致,需要借助指针的遍历来帮助访问节点,栈用来处理节点上的元素。不能提前将根节点放入栈中,如果先放入的话,迭代处理会先访问跟节点,而不是最左边的叶子节点。

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        
        res = []
        stack = []
        cur = root
        
        while cur or stack:
            #先迭代访问最左边的叶子节点
            if cur:
                stack.append(cur)
                cur = cur.left
            else:
                #此时cur = null
                cur = stack.pop()
                res.append(cur.val)
                cur = cur.right
        
        return res 

3.二叉树的统一迭代法

文档讲解: 代码随想录

题目链接:前序遍历

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        stack = []

        if root:
            stack.append(root)
        
        while stack:
            node = stack.pop()
            if node != None:
                if node.right:
                    stack.append(node.right)
                if node.left:
                    stack.append(node.left)
                stack.append(node)
                stack.append(None)
            else:
                node = stack.pop()
                res.append(node.val)
        return res

题目链接:后序遍历

class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        stack = []
        if root:
            stack.append(root)
        
        while stack:
            node = stack.pop()
            if node != None:
                stack.append(node)
                stack.append(None)
                if node.left:
                    stack.append(node.left)
                if node.right:
                    stack.append(node.right)
            else:
                node = stack.pop()
                res.append(node.val)
        
        return res

题目链接:中序遍历

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        stack = []
        if root:
            stack.append(root)
        
        while stack:
            node = stack.pop()
            if node != None:
                if node.right:
                    stack.append(node.right)
                stack.append(node)
                stack.append(None)
                if node.left:
                    stack.append(node.left)
            else:
                node = stack.pop()
                res.append(node.val)
        
        return res

4.102.二叉树的层序遍历

题目链接:102.二叉树的层序遍历
文档讲解: 代码随想录

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return []
        
        queue = collections.deque([root])
        res = []

        while queue:
            level = []
            for i in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
                
            res.append(level)
        return res

递归法:

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return []
        
        levels = []

        def traverse(node, level):
            if not node:
                return
            
            if len(levels) == level:
                levels.append([])
            
            levels[level].append(node.val)
            traverse(node.left, level + 1)
            traverse(node.right, level + 1)
        
        traverse(root, 0)
        return levels

扩展

107. 二叉树的层序遍历 II

题目链接:107

思路:在上题的基础上,输出的时候反转一下顺序。

class Solution(object):
    def levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return []
        
        res = []
        queue = collections.deque([root])

        while queue:
            level = []

            for i in range(len(queue)):
                node = queue.popleft()
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(level)
        return res[::-1]

199.二叉树的右视图

题目链接:199

一开始题目没有理解好,以为是将每层元素从右往左组成列表输出。题目要求的是只输出每层最右边元素组成的一维列表。

class Solution(object):
    def rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        res = []
        queue = collections.deque([root])
        
        while queue:
            #需要用变量存储长度,因为下面会对队列进行操作
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                
                if i == size - 1:
                    res.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return res

637.二叉树的层平均值

题目链接:637

class Solution(object):
    def averageOfLevels(self, root):
        """
        :type root: TreeNode
        :rtype: List[float]
        """
        if not root:
            return []
        queue = collections.deque([root])
        res = []
        while queue:
            summ = 0
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                summ += node.val
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(round(summ / size, 4))
        return res    

出现的问题:
在这里插入图片描述

将自己的代码替换到python3中是可行的,感觉是数据类型有点问题,具体是什么问题不能确认,暂时没有解决。

429.N叉树的层序遍历

题目链接:429

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: Node
        :rtype: List[List[int]]
        """

        if not root:
            return []
        res = []
        queue = collections.deque([root])
        while queue:
            level = []
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                level.append(node.val)
                #用for循环遍历孩子节点
                for child in node.children:
                    queue.append(child)
            res.append(level)
        return res 

515.在每个树行中找最大值

题目链接:515

class Solution(object):
    def largestValues(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """

        if not root:
            return []
        
        queue = collections.deque([root])
        res = []
        
         
        while queue:
            size = len(queue)
            maxx = queue[0].val#可以使用maxx = float('-inf')初始化

            for i in range(size):
                node = queue.popleft()
                if node.val > maxx:
                    maxx = node.val

                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(maxx)
        return res     

116.填充每个节点的下一个右侧节点指针

题目链接:116

class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        if not root:
            return root
        queue = collections.deque([root])
        while queue:
            size = len(queue)
            pre = None
            for i in range(size):
                node = queue.popleft()
                if pre:
                    pre.next = node
                pre = node
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

117. 填充每个节点的下一个右侧节点指针 II

题目链接:117

class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        if not root:
            return root
        queue = collections.deque([root])
        while queue:
            size = len(queue)
            pre = None 
            for i in range(size):
                node = queue.popleft()
                if pre:
                    pre.next = node
                pre = node
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

104. 二叉树的最大深度

题目链接:104

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        queue = collections.deque([root])
        deep = 0
        while queue:
            size = len(queue)
            deep += 1
            for i in range(size):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return deep

#111.二叉树的最小深度

题目链接:111

class Solution(object):
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0

        deep = 0
        queue = collections.deque([root])

        while queue:
            size = len(queue)
            deep += 1
            for i in range(size):
                node = queue.popleft()
                if not node.left and not node.right:
                    return deep
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return deep

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

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

相关文章

嵌入式C语言面试相关知识——关键字(不定期更新)

嵌入式C语言面试相关知识——关键字 一、博客声明二、C语言关键字1、sizeof关键字2、static关键字3、const关键字4、volatile关键字5、extern关键字 一、博客声明 又是一年一度的秋招,怎么能只刷笔试题目呢,面试题目也得看,想当好厂的牛马其实…

数据可视化之智慧城市的脉动与洞察

在数字化转型的浪潮中,城市作为社会经济发展的核心单元,正经历着前所未有的变革。城市数据可视化大屏看板作为这一变革中的重要工具,不仅极大地提升了城市管理效率,还为公众提供了直观、全面的城市运行状态视图,成为智慧城市建设不可或缺的一部分。本文将深入探讨以“城市…

一文理解 Treelite,Treelite 为决策树集成模型的部署和推理提供了高效、灵活的解决方案

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、什么是 Treelite? Treelite 是一个专门用于将决策树集成模型高效部署到生产环境中的机器学习模型编译器,特别适合处理大批量数据的推理任务,能够显著提升推理性能…

Java之网络面试经典题(一)

目录 ​编辑 一.Session和cookie Cookie Session 二.HTTP和HTTPS的区别 三.浅谈HTTPS为什么是安全的? 四.TCP和UDP 五.GET和Post的区别 六.forward 和 redirect 的区别? 本专栏全是博主自己收集的面试题,仅可参考,不能相…

嵌入式Linux系统编程 — 7.2 进程的环境变量

目录 1 什么是进程的环境变量 2 环境变量的作用 3 应用程序中获取环境变量 3.1 environ全局变量 3.2 获取指定环境变量 getenv 4 添加/删除/修改环境变量 4.1 putenv()函数添加环境变量 4.2 setenv()函数 4.3 unsetenv()函数 1 什么是进程的环境变量 每一个进程都有一…

Android - Json/Gson

Json数据解析 json对象:花括号开头和结尾,中间是键值对形式————”属性”:属性值”” json数组:中括号里放置 json 数组,里面是多个json对象或者数字等 JSONObject 利用 JSONObject 解析 1.创建 JSONObject 对象,传…

快手大模型首次集体亮相,用AI重塑内容与商业生态

7月6日,在2024世界人工智能大会期间,快手举办了以“新AI新应用新生态”为主题的大模型论坛,会上,快手大模型首次集体亮相,视频生成大模型可灵、图像生成大模型可图等产品的多项新功能正式发布。 继图生视频、视频续写…

Appium启动APP时报错Security exception: Permission Denial

报错内容Security exception: Permission Denial: starting Intent 直接通过am命令尝试也是同样的报错 查阅资料了解到:android:exported | App quality | Android Developers exported属性默认false,所以android:exported"false"修改为t…

QT学习积累——如何提高Qt遍历list的效率

目录 引出Qt遍历list提高效率显示函数的调用使用&与不使用&除法的一个坑 总结自定义信号和槽1.自定义信号2.自定义槽3.建立连接4.进行触发 自定义信号重载带参数的按钮触发信号触发信号拓展 lambda表达式返回值mutable修饰案例 引出 QT学习积累——如何提高Qt遍历list…

Springboot学习之用EasyExcel4导入导出数据(基于MyBatisPlus)

一、POM依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><m…

Kotlin中的数据类型

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

使用WinSCP工具连接Windows电脑与Ubuntu虚拟机实现文件共享传输

一。环境配置 1.首先你的Windows电脑上安装了VMware虚拟机&#xff0c;虚拟机装有Ubuntu系统&#xff1b; 2.在你的windows电脑安装了WinSCP工具&#xff1b; 3.打开WinSCP工具默认是这样 二。设置WinSCP连接 打开WinSCP&#xff0c;点击新标签页&#xff0c;进入到如下图的…

Ubuntu20.04配置TurtleBot3 Waffle Pi远程控制

这里写目录标题 0. 机器人配置1. Ubuntu20.04配置TurtleBot3 Waffle Pi远程控制1.1 TurtleBot3 Waffle Pi端配置1.2 PC端配置1.2.1 安装turtlebot3的环境配置1.2.2 创建项目并安装Turtlebot31.2.3 配置环境变量 1.3 PC端与TurtleBot3进行通信1.3.1 PC端与机器人端互PING和SSH连…

用C#调用Windows API向指定窗口发送按键消息详解与示例

文章目录 1. 按键消息的定义及功能2. 引入所需的命名空间3. 定义Windows API函数4. 定义发送消息的方法5. 获取窗口句柄6. 调用API发送按键消息7. 使用示例注意事项总结 在C#中调用Windows API向指定窗口发送按键消息是一种常见的操作&#xff0c;这通常用于自动化脚本、游戏辅…

加密货币大利好!9月降息概率突破70%!美国可能大幅降息或多次降息?

根据最新消息&#xff0c;美国9月降息的概率已经突破70%&#xff0c;这对加密货币市场来说是个利好消息。与此同时&#xff0c;美国经济表现疲软&#xff0c;可能会陷入衰退&#xff0c;联邦储备系统(Fed)接下来会不会果断采取大幅降息措施备受关注。 美国劳工统计局7月5日公布…

前端面试项目细节重难点(十)(已工作|做分享)

面试官&#xff1a;现场出需求&#xff1a;我想让一个左侧盒子可以进行拉伸、缩小、展示或隐藏这些功能&#xff0c;你会如何实现&#xff1f; 答&#xff1a;&#xff08;1&#xff09;分析问题&#xff1a;其实&#xff0c;我听到这个问题后&#xff1a; 我的第一种想法&am…

E1.【C语言】练习:用函数求两个整数的较大值

有关创建函数见&#xff1a; 12.【C语言】创建函数 写法 1&#xff1a;if语句 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int max(int a, int b) {if (a > b)return a;elsereturn b; } int main() {int a 0;int b 0;scanf("%d%d", &a,…

迎接AI新时代:GPT-5即将登场的巨大变革与应用前瞻

迎接AI新时代&#xff1a;GPT-5即将登场的巨大变革与应用前瞻 &#x1f48e;1. GPT-5 一年半后发布&#xff1a;AI新时代的来临1.1 GPT-5的飞跃&#xff1a;从高中生到博士生 &#x1f48e;2. GPT-5的潜在应用场景&#x1f48e;2.1 医疗诊断和健康管理&#x1f48e;2.2 教育领域…

生产力工具|VS Code安装及使用指南

一、VS Code介绍 &#xff08;一&#xff09;软件介绍 Visual Studio Code&#xff08;简称VS Code&#xff09;是由Microsoft开发的免费开源代码编辑器&#xff0c;适用于Windows、macOS和Linux操作系统。它支持多种编程语言&#xff0c;如JavaScript、Python、C等&#xff0…

Python爬虫获取视频

验证电脑是否安装python 1.winr输入cmd 2.在黑窗口输入 python.exe 3.不是命令不存在就说明python环境安装完成 抓取快手视频 1.在phcharm应用中新建一个项目 3.新建一个python文件 4.选择python文件,随便起一个名字后按回车 5.安装requests pip install requests 6.寻找需要的…