代码编织梦想

二叉树的前序遍历

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

示例 1:

在这里插入图片描述

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

示例 2:

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

示例 3:

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

示例 4:
在这里插入图片描述

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

示例 5:
在这里插入图片描述

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

Morris 遍历

思路:
有一种巧妙的方法可以在线性时间内,只占用常数空间来实现前序遍历。这种方法由 J. H. Morris 在 1979 年的论文「Traversing Binary Trees Simply and Cheaply」中首次提出,因此被称为 Morris 遍历。

Morris 遍历的核心思想是利用树的大量空闲指针,实现空间开销的极限缩减。其前序遍历规则总结如下:

  1. 新建临时节点,令该节点为 root;
  2. 如果当前节点的左子节点为空,将当前节点加入答案,并遍历当前节点的右子节点;
  3. 如果当前节点的左子节点不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点:
    • 如果前驱节点的右子节点为空,将前驱节点的右子节点设置为当前节点。然后将当前节点加入答案,并将前驱节点的右子节点更新为当前节点。当前节点更新为当前节点的左子节点。
    • 如果前驱节点的右子节点为当前节点,将它的右子节点重新设为空。当前节点更新为当前节点的右子节点。
  4. 重复步骤 2 和步骤 3,直到遍历结束。
    这样我们利用 Morris 遍历的方法,前序遍历该二叉树,即可实现线性时间与常数空间的遍历。

时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的节点数。没有左子树的节点只被访问一次,有左子树的节点被访问两次。
空间复杂度: O ( 1 ) O(1) O(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 preorderTraversal(self, root):
        results = []
        most_right = None
        while root:
            most_right = root.left
            if most_right:
                while most_right.right and most_right.right != root:
                    most_right = most_right.right
                if not most_right.right:
                    most_right.right = root
                    results.append(root.val)
                    root = root.left
                    continue
                else:
                    most_right.right = None
            else:
                results.append(root.val)
            root = root.right
        return results

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/binary-tree-preorder-traversal

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45616285/article/details/128012793

二叉树层次遍历:queue+每一层一个null标记-爱代码爱编程

题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。 思路: 一个Queue+每一层一个NULL标记 即可。 每当队列头部检测到NULL时,代表上一层的遍历已经结束,此时队列中存放的是下一层的节点,所以要在队列尾部中再添加一个NULL。

java 二叉树 常见操作合集(前中后序递归非递归遍历 层序遍历 求深度宽度 判断兄弟结点 堂兄弟节点)_我是叫帽帽啊的博客-爱代码爱编程

今天复习了二叉树的相关操作,整理归纳如下。 二叉树结点定义 //节点类 private static class TreeNode{ private int val = 0; private TreeNode left; private TreeNode right; publ

java实现--利用前序遍历将二叉树输出为括号字符串_猪饲夫妇、的博客-爱代码爱编程

将二叉树输出为括号字符串 题目描述: 需要采用前序遍历的方式,将二叉树转换为一个由括号和整数组成的字 符串。空间点则用一对空括号“()”表示。而且需省略所有不影响字符 串与原始二叉树之间的一对一映射关系的空括号对。 示

二叉树的前序遍历_light丶long的博客-爱代码爱编程

题目描述: 给定一个二叉树,返回它的 前序 遍历。  示例: 输入: [1,null,2,3]      1     \      2     /    3  输出: [1,2,3] 代码如下: /** * Definition for a binary tree node. * public class TreeNode { *

练手>一棵树的前序遍历为abe###cd,#为空节点null,构建二叉树_arize的博客-爱代码爱编程

1.若想返回多个值,可以创建一个结构体,返回结构体 2.递归创建二叉树 思路: 二叉树的根和size CreateTree(前序,size) { 终止条件: 1.遇到‘#’,return{NULL,1} 2.遇到si

【完整代码】二叉树的遍历与二叉树查找(Java实现)-爱代码爱编程

一、二叉树遍历 (1)前序遍历 步骤: 创建一棵二叉树先输出当前节点(根节点root)如果左子节点不为空,则递归继续前序遍历如果右子节点不为空,则递归继续前序遍历(2)中序遍历 步骤: 创建一棵二叉树如果当前节点的左子节点不为空,则递归中序遍历输出当前节点(root)如果当前节点的右子节点不为空,则递归中序遍历(3)后序遍历 步骤: 创建一棵二叉树

层序遍历是否需要存空结点的问题思考-爱代码爱编程

目前接触到的层序遍历有两种,一是只存非空结点,二是空结点和非空结点都存 区别: 第一种情况,不存,涉及提取队列长度queue.size(),如果存空结点会影响实际情况 第二种情况,存,涉及两个树的比较,所以位置需要一一对应,空结点对空结点   一是:判断是否为空结点,非空结点才存到队列中,出队是的结点都是非空结点,队列中的结点都是实实在在存在的结

【LeetCode】144. 二叉树的前序遍历-爱代码爱编程

题目 给定一个二叉树,返回它的 前序 遍历。  示例: 输入: [1,null,2,3]      1     \      2     /    3  输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路 方法一:递归 思路与算法 首先我们需要了解什么是二叉树的前序遍历:按照访问根节点——左子树——右子树

jquer each 遍历的结果不显示 null_SpringBoot系列(三十一)- Thymeleaf如何用th:each 做条件遍历-爱代码爱编程

步骤1:基于前面的知识点步骤2:先运行,看到效果,再学习步骤3:模仿和排错步骤4:TestController步骤5:普通遍历步骤6:带状态的遍历步骤7:结合 select步骤8:结合 单选框步骤9:完整的 test.html步骤10:重启测试 步骤 1 : 基于前面的知识点本知识点是建立在上一个知识点可运行项目的基础上进行的改进,所以最好把上个知识

jquer each 遍历的结果不显示 null_6.3 二叉树的遍历与线索化(2)-爱代码爱编程

返回目录: Chilan Yu:《数据结构》目录链接​zhuanlan.zhihu.com 6.3.2 遍历算法应用 1. 输出二叉树中的结点 可以用三种遍历算法中的任何一种完成,只需要将访问操作具体变为输出操作即可。 /*先序遍历输出二叉树中的结点(根左右)*/ /*中序遍历输出二叉树中的结点

c语言百日千题系列之《忘情水题》第一日_会敲代码的史蒂夫.的博客-爱代码爱编程

目录 绪论 1.最大数位置 2.与指定数字相同的数的个数 3.蓝桥杯2013年第四届真题-核桃的数量 4.求所给范围内水仙花数并排列 5.最大值和最小值的差 6.计算书费 7.角谷猜想 8. 最高的分数 9.年龄与疾病 10.-百钱百鸡问题 绪论       本文是C语言百日千题系列《忘情水题》的第一篇专栏文章,主要为初学

2022大厂面试秘籍java岗:中间件+算法+http+线程+虚拟机+分布式_啊码的博客-爱代码爱编程

前言 很多朋友对面试不够了解,不知道如何准备,对面试环节的设置以及目的不够了解,因此成功率不高。通常情况下校招生面试的成功率低于1%,而社招的面试成功率也低于5%,所以对于候选人一定要知道设立面试的初衷以及每个环节的意义,

【csdn竞赛】第十期解题报告_icehomegre的博客-爱代码爱编程

文章目录 感想关于自己关于平台 第一题 (难度:入门)题目描述100分做法 第二题 (难度:简单)题目描述100分做法 第三题 (难度:中等/困难)题目描述100分做法1(对应中等)10

c++类与对象(一)-爱代码爱编程

目录 一、面向过程和面向对象认识 二、类的引入 三、类的定义 类的两种定义方式: 四、类的访问限定符及封装 4.1 访问限定符 4.2 封装 五、类的作用域 六、类的实例化 七、类对象模型 7.1 如何计算类对象的大小​​​​​ 7.2 类对象的存储方式 7.3 结构体内存对齐规则 八、this指针 8.1 this指针的引出