代码随想录算法训练营第14天 |● 理论基础 ● 递归遍历 ● 迭代遍历 ● 统一迭代

news2024/10/5 18:03:55

文章目录

  • 前言
  • 二叉树的递归遍历
    • 💖递归算法基本要素
    • 代码
  • 迭代遍历-需要先理清思路再写
    • 前向迭代法
    • 后序迭代
    • 中序迭代
  • 迭代法统一写法
  • 总结


前言

理论基础

需要了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义
记录我容易忘记的点
在这里插入图片描述
在这里插入图片描述
题目一半都是用链式存储来做,但是可以稍微了解一下顺序存储
在这里插入图片描述
定义的代码
在这里插入图片描述
在这里插入图片描述

二叉树的递归遍历

前中后分别对应力扣的144,94,145

💖递归算法基本要素

这个主要用于打基础,后面所有二叉树的题目都需要用这个来做。
这里帮助大家确定下来递归算法的三个要素。每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!

确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程

代码

dfs函数可以写在里面,不用额外写一个self.dfs在外面

class Solution(object):

    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        vec = []
        def dfs(node):
            if not node:
                return
            vec.append(node.val)
            dfs(node.left)
            dfs(node.right)
        dfs(root)
        return vec
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        vec = []
        def dfs(node):
            if not node:
                return
            
            dfs(node.left)
            vec.append(node.val)
            dfs(node.right)
        dfs(root)
        return vec 
            def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        vec = []
        def dfs(node):
            if not node:
                return
            dfs(node.left)            
            dfs(node.right)
            vec.append(node.val)
        dfs(root)
        return vec        

迭代遍历-需要先理清思路再写

为什么有了递归还要迭代:因为面试的时候有可能会问你能不能用除了递归别的方法。

递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

此时大家应该知道我们用栈也可以是实现二叉树的前后中序遍历了。【看动图过程】

前向迭代法

根左右
首先根节点入栈,然后紧跟着弹出给到result数组里面,然后压入右节点和左【先右再左是为了出栈顺序是左右】

  • 也就是压入一个根节点之后,弹出,紧跟着再压入它的左右两个节点;到下一轮循环里面,弹出根节点,然后再压入它的右左节点;
    在这里插入图片描述

在这里插入图片描述
if not root: return : 这一行代码不要忘了,有可能传入的root是空的。

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

        # 非迭代法
        if not root: return
        result = []
        stack =[root]
        while stack:#如果还有节点:
            node = stack.pop()
            result.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return result

后序迭代

左右根
在这里插入图片描述

只需要对先序做两个调整:交换左右,reverse result数组

    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
                # 代法
        if not root: return
        result = []
        stack =[root]
        while stack:#如果还有节点:
            node = stack.pop()
            result.append(node.val)
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
        return result[::-1]

中序迭代

思路:根节点一路压栈,知道左节点为空之后,弹出该节点【已经判断了左(为空)和中(弹出)】,然后判断右节点,不为空就压入右节点,判断这个右节点;为空的话就弹出栈口的节点,再判断新弹出的右节点是否为空;

  • 左节点为空之后,就从栈弹出中间节点然后判断右节点【从栈顶弹出的元素是最近访问的元素 】
    具体实现:加了一个指针curr
    在这里插入图片描述

错的地方都写了注释

# 中序遍历-迭代-LC94_二叉树的中序遍历
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:#这个别忘了
            return []
        stack = []  # 不能提前将root结点加入stack中
        result = []
        cur = root
        while cur or stack:#如果cur和stack都是空的话
            # 先迭代访问最底层的左子树结点
            if cur:     
                stack.append(cur)#压入的是node啊,别写成val了
                cur = cur.left		
            # 到达最左结点后处理栈顶结点    
            else:		
                cur = stack.pop()
                result.append(cur.val)
                # 取栈顶元素右结点
                cur = cur.right	
        return result

迭代法统一写法

没看。carl说这个思路有点抽象,而且面试的时候很难一下子写对,就算了吧。我也没看懂。。。。

总结

晚上无论如何也要把实习简历写一半。所以不磕了

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

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

相关文章

打造AI虚拟伴侣 - 优化方案

第一部分:框架优化概述 1、精确定位: 构建一个高度灵活且用户友好的平台,旨在通过无缝集成多种大型语言模型(LLMs)后端,为用户创造沉浸式的角色交互体验。不仅适配电脑端,还特别优化移动端体验,满足二次元AI虚拟伴侣市场的特定需求。 2、核心功能强化: 增强后端兼容…

大数据Hive中的UDF:自定义数据处理的利器(下)

在上一篇文章中,我们对第一种用户定义函数(UDF)进行了基础介绍。接下来,本文将带您深入了解剩余的两种UDF函数类型。 文章目录 1. UDAF1.1 简单UDAF1.2 通用UDAF 2. UDTF3. 总结 1. UDAF 1.1 简单UDAF 第一种方式是 Simple(简单…

叶面积指数(LAI)数据、NPP数据、GPP数据、植被覆盖度数据获取

引言 多种卫星遥感数据反演叶面积指数(LAI)产品是地理遥感生态网推出的生态环境类数据产品之一。产品包括2000-2009年逐8天数据,值域是-100-689之间,数据类型为32bit整型。该产品经过遥感数据获取、计算归一化植被指数、解译植被类…

测量模拟量的优选模块:新型设备M-SENS3 8

| 具有8路自由选择通道的新型设备M-SENS3 8 IPETRONIK推出的模拟量测量设备——M-SENS3 8是新一代设备的新成员。该模块具有8个通道,能够自由选择测量模式,不仅支持高精度电压和电流的测量,还新增了频率测量模式。各通道分辨率高达18位&…

Selenium常用命令(python版)

日升时奋斗,日落时自省 目录 1、Selenium 2、常见问题 1、Selenium 安装Python和配置环境没有涉及 注:如有侵权,立即删除 首先安装selenium包,安装方式很简单 pip install selenium 注:我这里已经安装好了,所以…

spring boot集成Knife4j

文章目录 一、Knife4j是什么?二、使用步骤1.引入依赖2.新增相关的配置类3.添加配置信息4.新建测试类5. 启动项目 三、其他版本集成时常见异常1. Failed to start bean ‘documentationPluginsBootstrapper2.访问地址后报404 一、Knife4j是什么? 前言&…

弘君资本股市行情:股指预计保持震荡上扬格局 关注汽车、银行等板块

弘君资本指出,近期商场体现全体分化,指数层面上看,沪指一路震动上行,创出年内新高,创业板指和科创50指数体现相对较弱,依然是底部震动走势。从盘面体现上看,轮动依然是当时商场的主基调&#xf…

逻辑分析仪 - 采样率/采样深度

采样深度(Sampling Depth) 采样深度指的是逻辑分析仪在一次捕获过程中可以记录的最大样本数量。简单来说,采样深度越大,逻辑分析仪可以记录的数据量就越多。这对于分析长时间的信号变化或复杂的信号序列非常重要。 采样率&#…

WEB攻防【2】——ASPX/.NET项目/DLL反编译/未授权访问/配置调试报错

ASP:windowsiisaspaccess .net:windowsiisaspxsqlserver IIS上的安全问题也会影响到 WEB漏洞:本身源码上的问题 服务漏洞:1、中间件 2、数据库 3、第三方软件 #知识点: 1、.NET:配置调试-信息泄绵 2、.NET:源码反编译-DLL…

使用Flask ORM进行数据库操作的技术指南

文章目录 安装Flask SQLAlchemy配置数据库连接创建模型类数据库操作插入数据查询数据更新数据删除数据 总结 Flask是一个轻量级的Python Web框架,其灵活性和易用性使其成为开发人员喜爱的选择。而ORM(对象关系映射)则是一种将数据库中的表与面…

HCIP-Datacom-ARST自选题库__OSPF单选【80道题】

1.OSPFV2是运行在IPV4网络的IGP,OSPFV3是运行在IPV6网络的ICP,OSPFV3与OSPFv2的报文类型相同,包括Hello报文、DD报文、LSR报文、LSU报文和LSAck报文。关于OSPFv3报文,以下哪个说法是正确的 OSPFv3使用报文头部的认证字段完成报文…

揭秘齿轮加工工艺的选用原则:精准打造高效传动的秘密武器

在机械制造领域,齿轮作为传动系统中的重要组成部分,其加工工艺的选择至关重要。不同的齿轮加工工艺会影响齿轮的精度、耐用性和效率。本文将通过递进式结构,深入探讨齿轮加工工艺的选用原则,带您了解如何精准打造高效传动的秘密武…

最简单的 UDP-RTP 协议解析程序

最简单的 UDP-RTP 协议解析程序 最简单的 UDP-RTP 协议解析程序原理源程序结果下载链接参考 最简单的 UDP-RTP 协议解析程序 本文介绍网络协议数据的处理程序。网络协议数据在视频播放器中的位置如下所示。 本文中的程序是一个 UDP/RTP 协议流媒体数据解析器。该程序可以分析 …

Java | Leetcode Java题解之第109题有序链表转换二叉搜索树

题目: 题解: class Solution {ListNode globalHead;public TreeNode sortedListToBST(ListNode head) {globalHead head;int length getLength(head);return buildTree(0, length - 1);}public int getLength(ListNode head) {int ret 0;while (head…

彩虹聚合二级域名DNS管理系统源码v1.3

聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析, 目前已支持的域名平台有:阿里云、腾讯云、华为云、西部数码、CloudFlare。 本系统支持多用户,每个用户可分配不同的域名解析权限;支持API接口, 支持获…

结合反序列化注入tomcat内存马

0x01 前提概述 通过前几个内存马的学习我们可以知道,将内存马写在jsp文件上传并不是传统意义上的内存马注入,jsp文件本质上就是一个servlet,servlet会编译成class文件,也会实现文件落地。借用木头师傅的一张图 结合反序列化注入内…

​​​【收录 Hello 算法】10.1 二分查找

目录 10.1 二分查找 10.1.1 区间表示方法 10.1.2 优点与局限性 10.1 二分查找 二分查找(binary search)是一种基于分治策略的高效搜索算法。它利用数据的有序性,每轮缩小一半搜索范围,直至找到目标元素或搜索区间为空…

Python | Leetcode Python题解之第110题平衡二叉树

题目: 题解: class Solution:def isBalanced(self, root: TreeNode) -> bool:def height(root: TreeNode) -> int:if not root:return 0leftHeight height(root.left)rightHeight height(root.right)if leftHeight -1 or rightHeight -1 or a…

【论文笔记】| 定制化生成PuLID

PuLID: Pure and Lightning ID Customization via Contrastive Alignment ByteDance, arXiv:2404.16022v1 Theme: Customized generation 原文链接:https://arxiv.org/pdf/2404.16022 Main Work 提出了 Pure 和 Lightning ID 定制 (PuLID),这是一种用于…

Golang | Leetcode Golang题解之第109题有序链表转换二叉搜索树

题目: 题解: var globalHead *ListNodefunc sortedListToBST(head *ListNode) *TreeNode {globalHead headlength : getLength(head)return buildTree(0, length - 1) }func getLength(head *ListNode) int {ret : 0for ; head ! nil; head head.Next…