leetcode二叉树(三)-二叉树的迭代遍历

news/2024/10/22 14:42:40/

题目


144.二叉树的前序遍历

145.二叉树的后序遍历

94.二叉树的中序遍历
 

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

示例 1:

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

输出:[1,2,3]

解释:

示例 2:

输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出:[1,2,4,5,6,7,3,8,9]

解释:

示例 3:

输入:root = []

输出:[]

示例 4:

输入:root = [1]

输出:[1]

思路

前序遍历(迭代法)

前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。

为什么要先加入 右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。

后序遍历(迭代法)

先序遍历是中左右,后序遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了,如下图:

中序遍历(迭代法)

在遍历过程中有两个操作:

  1. 处理:将元素放进result数组中
  2. 访问:遍历节点

分析一下为什么刚刚写的前序遍历的代码,不能和中序遍历通用呢,因为前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以刚刚才能写出相对简洁的代码,因为要访问的元素和要处理的元素顺序是一致的,都是中间节点。

那么再看看中序遍历,中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。

那么在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。

代码

前序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
#使用迭代法实现
class Solution:def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:if not root:return []nums = []stack = [root]while stack:temp = stack.pop()nums.append(temp.val)if temp.right:stack.append(temp.right)if temp.left:stack.append(temp.left)return nums

后序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
#迭代法实现
class Solution:def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:if not root:return []nums = []stack = [root]while stack:temp = stack.pop()nums.append(temp.val)if temp.left:stack.append(temp.left)if temp.right:stack.append(temp.right)return nums[::-1]

中序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
#迭代法
class Solution:def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:if not root :return []stack =[]result = []cur = rootwhile cur or stack:#cur或者stack中有一个不为空,都一直继续if cur:#如果当前节点不为空的时候,就将当前节点指向该节点的左子树stack.append(cur)cur = cur.leftelse:#如果当前节点为空,那就需要从stack中取出最后一个节点,中序遍历,这个就是中间那个数,再指向右子树cur = stack.pop()result.append(cur.val)cur = cur.rightreturn result


http://www.ppmy.cn/news/1538984.html

相关文章

从零开始学英语:三个月学习计划(每天30分钟到1小时)

导语 对于工作繁忙的上班族,利用每天30分钟到1小时进行英语学习是非常现实的。以下是一个适合这样的时间安排的学习计划,旨在帮助你在三个月内打下英语基础,提高听说读写能力。 第一月:基础入门 目标:掌握基本词汇和…

光路科技以技术创新为驱动,打造创新型企业新标杆

近日,深圳市光路在线科技有限公司(光路科技)凭借其出色的创新能力和市场表现,荣获深圳市中小企业服务局颁发的“创新型中小企业”称号。这一荣誉标志着光路科技在推动行业发展和技术进步方面取得了显著成就。 光路科技自2008年成立…

加固与脱壳07 - 修改源码脱壳

​上文我们讨论了该如何脱壳,现在就开始实现吧。 本文不介绍如何编译源码,这块内容之前已经单独发过了,可以使用虚拟机或者 WSL,WSL体验要好些,虚拟机更方便。 看开源项目: https://github.com/dqzg12300…

Golang | Leetcode Golang题解之第462题最小操作次数使数组元素相等II

题目&#xff1a; 题解&#xff1a; func partition(a []int, l, r int) int {x : a[r]i : l - 1for j : l; j < r; j {if a[j] < x {ia[i], a[j] a[j], a[i]}}a[i1], a[r] a[r], a[i1]return i 1 }func randomPartition(a []int, l, r int) int {i : rand.Intn(r-l1…

【进阶OpenCV】 (12)--人脸检测识别

文章目录 人脸识别一、获取分类器二、代码实现1. 图片预处理2. 加载人脸检测分类器3. 检测人脸4. 标注人脸 总结 人脸识别 要实现人脸识别首先要判断当前图像中是否出现了人脸&#xff0c;这就是人脸检测。只有检测到图像中出现了人脸&#xff0c;才能据此判断这个人到底是谁。…

QD1-P23 CSS 基础选择器

本节学习&#xff1a;CSS 基础选择器&#xff08;5种&#xff09; 本节视频 https://www.bilibili.com/video/BV1n64y1U7oj?p23 基础选择器是 CSS 中最常用的选择器类型&#xff0c;它们用于选择 HTML 文档中的元素。以下是基础选择器的列表以及它们的优先级&#xff08;权重…

Redis 列表(List)

Redis 列表(List) Redis 是一个开源的&#xff0c;内存中的数据结构存储系统&#xff0c;可以用作数据库、缓存和消息中介。它支持多种类型的数据结构&#xff0c;包括字符串、哈希、列表、集合、有序集合等。本文将重点介绍 Redis 中的列表&#xff08;List&#xff09;数据结…

docker详解介绍+基础操作 (四)容器镜像

一.镜像结构和原理 Docker 镜像是 Docker 技术的核心组成部分之一&#xff0c;它用于封装应用程序及其依赖项&#xff0c;以便在任何支持 Docker 的环境中运行。了解 Docker 镜像的结构和原理对于有效使用 Docker 至关重要。以下是对 Docker 镜像结构和原理的详细介绍。 Dock…