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

news2024/10/5 13:14:02

打卡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.coloradmin.cn/o/1900992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ctfshow web入门 web338--web344

web338 原型链污染 comman.js module.exports {copy:copy };function copy(object1, object2){for (let key in object2) {if (key in object2 && key in object1) {copy(object1[key], object2[key])} else {object1[key] object2[key]}}}login.js var express …

Python + 在线 + 文生音,音转文(中文文本转为英文语音,语音转为中文文本)

开源模型 平台:https://huggingface.co/ars-语言转文本: pipeline("automatic-speech-recognition", model"openai/whisper-large-v3", device0 ) hf: https://huggingface.co/openai/whisper-large-v3 github: https://github.com/openai/wh…

使用自动化测试确保接口正确性的详细指南!

引言: 随着软件开发的迅速发展,接口的正确性成为了确保应用程序质量的关键要素之一。自动化测试是一种强大的工具,可以帮助开发人员和测试人员减少错误,提高测试覆盖率,并加快测试过程。本文将详细介绍从零开始如何使…

探索LlamaIndex:如何用Django打造高效知识库检索

简介 LlamaIndex(前身为 GPT Index)是一个数据框架,为了帮助我们去建基于大型语言模型(LLM)的应用程序。 主要用于处理、构建和查询自定义知识库。 它支持多种数据源格式 excel,txt,pdf&…

ELK优化之Filebeat部署

目录 1.安装配置Nginx 2.安装 Filebeat 3.设置 filebeat 的主配置文件 4.修改Logstash配置 5.启动配置 6.kibana验证 主机名ip地址主要软件es01192.168.9.114ElasticSearches02192.168.9.115ElasticSearches03192.168.9.116ElasticSearch、Kibananginx01192.168.9.113ng…

测试人员如何管理项目与风险预警

在平时工作过程中,你有没有因项目延时,需求频繁变更,开发提测质量不高,以及漏测的情况下,背了不少锅的情况呢? 作为测试人员,我们应该如何发挥积极主动性,进行项目管理,有…

VuePress 的更多配置

现在,读者应该对 VuePress、主题和插件等有了基本的认识,除了插件,VuePress 自身也有很多有用的配置,这里简单说明下。 ‍ ‍ VuePress 的介绍 在介绍了 VuePress 的基本使用、主题和插件的概念之后,我们再来看看官…

CTS单测某个模块和测试项

1 &#xff0c;测试单个模块命令 run cts -m <模块名> 比如&#xff1a;run cts -m CtsUsbTests模块名可以从测试报告中看&#xff0c;如下&#xff1a; 2&#xff0c; 测试单个测试项 run cts -m <模块名> -t <test_name> 比如&#xff1a;run cts -m ru…

基于大象机器人UltraArm P340机械臂和传送带,实现教育场景中的自动化分拣系统!

引言 今天我们将展示一个高度自动化的模拟场景&#xff0c;展示多个机械臂与传送带协同工作的高效分拣系统。在这个场景中&#xff0c;机械臂通过视觉识别技术对物体进行分类&#xff0c;并通过精确的机械操作将它们放置在指定的位置。这一系统不仅提高了分拣的速度和准确性&am…

dotnet ef工具使用

设置工具安装目录 dotnet tool install dotnetsay --tool-path G:\dotnet-tools安装 dotnet tool install --global dotnet-ef更新 dotnet tool update --global dotnet-ef查看版本 dotnet ef --version创建迁移文件 # 只有一个dbcontext dotnet ef migrations add init #…

http读书笔记

持久化 HTTP/1.1 和一部分的 HTTP/1.0 想出了 持久连接&#xff08;HTTP Persistent Connections&#xff0c; 也称为 HTTP keep-alive 或 HTTP connection reuse&#xff09; 的方法。 持久连接的特点是&#xff0c; 只要任意一端 没有明确提出断开连接&#xff0c; 则保持 T…

mysql 9 新特新

mysql9新特性 新特性Audit Log NotesC API NotesCharacter Set SupportCompilation NotesComponent NotesConfiguration NotesData Dictionary NotesData Type NotesDeprecation and Removal NotesEvent Scheduler NotesJavaScript ProgramsOptimizer NotesPerformance Schema …

微机原理与单片机 知识体系梳理

单片机笔记分享 我个人感觉单片机要记的东西很多&#xff0c;也很琐碎&#xff0c;特别是一些位、寄存器以及相关作用等&#xff0c;非常难以记忆。因此复习时将知识点整理在了一起做成思维导图&#xff0c;希望对大家有所帮助。内容不是很多&#xff0c;可能有些没覆盖全&…

轻预压:滚珠丝杆精度与刚性的平衡点!

预压是指在所需的工作负荷下&#xff0c;使滚珠丝杆预先承受一定的负荷&#xff0c;从而使滚珠丝杆的轴向向心度和侧向偏差达到较小的偏差范围&#xff0c;保证了滚珠丝杆的准确性和稳定性&#xff0c;也确保机器的高精度和长期运作的可靠性。 预压是滚珠丝杆设计中的一个重要参…

基于Java技术的人事管理系统

你好&#xff0c;我是专注于计算机科学领域的小野。如果你对人事管理系统感兴趣或有相关需求&#xff0c;欢迎私信交流。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; B/S模式、Java技术、SpringBoot 工具&#xff1a; Eclipse、MySQL、浏览…

Selenium 切换 frame/iframe

环境&#xff1a; Python 3.8 selenium3.141.0 urllib31.26.19说明&#xff1a; driver.switch_to.frame() # 将当前定位的主体切换为frame/iframe表单的内嵌页面中 driver.switch_to.default_content() # 跳回最外层的页面# 判断元素是否在 frame/ifame 中 # 126 邮箱为例 # …

基于若依的文件上传、下载

基于若依实现文件上传、下载 文章目录 基于若依实现文件上传、下载1、前端实现-文件上传1.1 通用上传分析1.2 修改实现上传接口 2、后端实现-文件上传3、后端实现-文件下载4、前端实现-文件下载 官网其实也写了&#xff0c;但是我是自己改造封装了一下&#xff0c;再次迈向全栈…

vofa+:一款超级好用的可视化串口调试软件

目录 一、软件配置 1、先配置好usart1串口 2、重定向printf: 3&#xff0c;勾选魔术棒中的LIB 二、vofa的使用 1、RawData模式 2、FireWater 一、软件配置 1、先配置好usart1串口 2、重定向printf: 在 stm32f4xx_hal.c中添加&#xff1a; #include <stdio.h> e…

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

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

VBA初学:零件成本统计之一(任务汇总)

经过前期一年多对金蝶K3生产任务流程和操作的改造和优化&#xff0c;现在总算可以将零件加工各个环节的成本进行归集了。 原本想写存储过程&#xff0c;通过直接SQL报表做到K3中去的&#xff0c;但财务原本就是用EXCEL&#xff0c;可以方便调整和保存&#xff0c;加上还有一部分…