前序遍历、后序遍历-morris

news2024/11/28 2:42:39

前序遍历

前序遍历:中 -> 左子树 -> 右子树

非递归的遍历-stack

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (null == root) {
            return res;
        }
        LinkedList<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            res.add(node.val);
            if (null != node.right) {
                stack.push(node.right);
            }
            if (null != node.left) {
                stack.push(node.left);
            }
        }
        return res;
    }

morris

空间复杂度为O(1)

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if (root == null) {
            return res;
        }
        TreeNode cur = root;
        while (cur != null) {
            // 左子树不为null,优先处理
            if (null != cur.left) {
                TreeNode leftMaxRight = cur.left;
                while (leftMaxRight.right != null && leftMaxRight.right != cur) {
                    leftMaxRight = leftMaxRight.right;
                }
                // leftMaxRight为叶子结点,right==null表示 要续上;否则表示 已经处理完,要恢复
                if (leftMaxRight.right == null) {
                    res.add(cur.val);
                    // 续上 连接,指向中序排序下一个结点:leftMaxRight若为左子树,则right=parent; 若为右子树,则right = 所在树的root.root
                    leftMaxRight.right = cur;
                    cur = cur.left;
                    continue;
                } else {
                    // leftMaxRight为叶子结点,将续上的连接 恢复null值
                    leftMaxRight.right = null;
                }
            } else {
                // 1) 非叶子结点,左子树为null,直接添加cur,再处理其右子树
                // 2) 叶子结点,右子树 为 续上 的连接,指向中序排序下一个结点
                res.add(cur.val);
            }
            // 1)cur及其左子树 处理完后,处理右子树
            // 2)cur为叶子节点时,cur.right为 其 中序 遍历的 下一个节点
            cur = cur.right;
        }
        return res;
    }

遍历时续上的连接 如下所示,指向 中序遍历 的下一个结点,node5.right=node1, node4.right = node2
在这里插入图片描述
1: 5->1, 输出1,进入2
2: 4->2, 输出2,进入4
4: 输出4,进入2

2: 断开 4->2, 进入5
5:输出5,进入1

1: 断开5->1, 进入3
3: 6->3, 输出3,进入6
6: 输出6,进入3
3: 断开6->3, 进入7
7: 输出7
最终序列为:1、2、4、5、3、6、7

力扣上的题目:
https://leetcode.cn/problems/binary-tree-preorder-traversal/solutions/461821/er-cha-shu-de-qian-xu-bian-li-by-leetcode-solution/?company_slug=meituan

后序遍历(中序也参考这个吧)

左子树 -> 右子树 -> root

morris

public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (null == root) {
            return res;
        }
        TreeNode cur = root;
        while (null != cur) {
            if (null != cur.left) {
                TreeNode leftMaxRight = cur.left;
                while (leftMaxRight.right != null && leftMaxRight.right != cur) {
                    leftMaxRight = leftMaxRight.right;
                }
                if (leftMaxRight.right == null) {
                    // 续上, 中序遍历的下一个结点
                    leftMaxRight.right = cur;
                    cur = cur.left;
                    continue;
                } else {
                    // 将续上的干掉
                    leftMaxRight.right = null;
                    // 叶子结点 在 第2次遍历到其parent时,才会处理
                    addNodeRight(res, cur.left);
                }
            } 
            cur = cur.right;
        }
        // 处理最后的右子树横线
        addNodeRight(res, root);
        return res;
    }
    // 处理node开始的右子树 线
    public void addNodeRight(List<Integer> res, TreeNode node) {
        int left = res.size();
        while (null != node) {
            res.add(node.val);
            node = node.right;
        }
        int right = res.size() - 1;
        // left为第一个插入位置,right为最后插入位置
        // 将left和right范围内 倒转
        while (left < right) {
            int tmp = res.get(left);
            res.set(left, res.get(right));
            res.set(right, tmp);
            left++;
            right--;
        }
    }

在这里插入图片描述
leetcode题目地址:https://leetcode.cn/problems/binary-tree-postorder-traversal/submissions/?company_slug=meituan

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

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

相关文章

基于 VSC 的 UPFC(统一潮流控制器)研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

EM算法和VAE的学习笔记

文章目录 摘要EM算法流程EM算法对GMM的参数估计EM算法的证明EM算法的另一种理解VAE参考文献 摘要 这是我学习EM算法&#xff08;Expectation-Maximization Algorithm&#xff09;和VAE&#xff08;Variational Auto-Encoder&#xff09;的学习笔记&#xff0c;首先总结了EM算法…

day5ARM

循环点亮三个led灯 方法1 ------------------led.h---------------- #ifndef __LED_H__ #define __LED_H__#define RCC (*(volatile unsigned int *)0x50000A28) #define GPIOE ((GPIO_t *)0x50006000) #define GPIOF ((GPIO_t *)0x50007000)//结构体封装 typedef struct {vo…

天空飞鸟 数据集

今天要介绍的数据集则是天空飞鸟 数据集&#xff1a; 数据集名称&#xff1a;天空飞鸟 数据集 数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;以文件包含图片…

alova.js快速入门教程

官网地址&#xff1a;Alova.JS - Lightweight request strategy library | Alova.JS 目录 一、alova 是什么&#xff1f; 二、 快速入门 1、安装依赖 &#xff08;1&#xff09;使用npm方式安装 &#xff08;2&#xff09;使用yarn方式安装 2、在静态 html 中使用 一、al…

CAD for JS:VectorDraw web library 10.1004.1 Crack

VectorDraw web library经过几年的研究&#xff0c;通过互联网展示或工作的可能性并拒绝了各种项目&#xff0c;我们最终得出的结论是&#xff0c;在 javascript 的帮助下&#xff0c;我们将能够在 Microsoft IE 以外的互联网浏览器中通过网络演示矢量图形&#xff08;支持 ocx…

NSSCTF之Misc篇刷题记录(17)

NSSCTF之Misc篇刷题记录&#xff08;17&#xff09; [闽盾杯 2021]DNS协议分析[GFCTF 2021]pikapikapika NSSCTF平台&#xff1a;https://www.nssctf.cn/ PS&#xff1a;所有FLAG改为NSSCTF [闽盾杯 2021]DNS协议分析 数据包提示给得是DNS数据包 直接过滤一下 发现 数据里面存…

分支和远程仓库

分支 查看分支 git branch -v 创建分支 git branch 分支名 切换分支 git checkout 分支名 合并分支 git merge 分支名 把指定的分支合并到当前分支上 查看当前所有远程地址别名&#xff1a; git remote -v 起别名&#xff1a; git remote add 别名 远程地址推送本地分支上的…

【已解决】qt死活不响应鼠标移动到按钮事件

本博文源于笔者正在研究的内容&#xff0c;这个问题大概捣鼓了一个下午&#xff0c;问题是这样子&#xff1a;我有一个按钮&#xff0c;我应用程序运行时&#xff0c;我鼠标放到按钮上&#xff0c;按钮就会被填充图标。怀揣着这样一个想法&#xff0c;我搜啊搜&#xff0c;整啊…

探讨基于IEC61499 的分布式 ISA Batch 控制系统

ISA SP88 是批次过程控制的标准&#xff0c;对应的IEC标准是IEC 61512。该标准中一个重要的部分是配方管理&#xff08;Recipe Management&#xff09;。 所谓配方&#xff0c;是根据批量产品的要求&#xff0c;材料设定加工工艺&#xff0c;加工流程和参数。类似于传统制造业的…

IntelliJ IDEA使用——Debug操作

文章目录 版本说明图标和快捷键查看变量计算表达式条件断点多线程调试 版本说明 当前的IntelliJ IDEA 的版本是2021.2.2&#xff08;下载IntelliJ IDEA&#xff09; ps&#xff1a;不同版本一些图标和设置位置可能会存在差异&#xff0c;但应该大部分都差不多。 图标和快捷键…

STM32单片机——看门狗(独立看门狗窗口看门狗)

STM32单片机——看门狗&#xff08;独立看门狗&窗口看门狗&#xff09; 独立看门狗&#xff08;IWDG&#xff09;独立看门狗本质相关概念独立看门狗实验CubeMX工程配置HAL库程序设计固件库程序设计 窗口看门狗&#xff08;WWDG&#xff09;独立看门狗本质相关概念窗口看门狗…

购物H5商城架构运维之路

一、引言 公司属于旅游行业&#xff0c;需要将旅游&#xff0c;酒店&#xff0c;购物&#xff0c;聚合到线上商城。通过对会员数据进行聚合&#xff0c;形成大会员系统&#xff0c;从而提供统一的对客窗口。 二、业务场景 围绕更加有效地获取用户&#xff0c;提升用户的LTV&a…

mysql 半同步复制模式使用详解

目录 一、前言 二、mysql主从架构简介 2.1 mysql主从复制架构概述 2.2 为什么使用主从架构 2.2.1 提高数据可用性 2.2.2 提高数据可靠性 2.2.3 提升数据读写性能 2.3 主从架构原理 2.4 主从架构扩展 2.4.1 双机热备&#xff08;AB复制&#xff09; 2.4.2 级联复制 2…

驱动开发,基于中断子系统完成按键的中断驱动,引入中断底半部

一.引入linux内核中断目的 引入linux内核中断之前&#xff0c;内核访问设备要不断轮询访问&#xff1b; 引入linux内核中断便于内核对设备的访问&#xff0c;当设备事件发生后主动通知内核&#xff0c;内核再去访问设备&#xff1b; 二.linux内核中断实现过程框图 根据软…

STM32F103RCT6学习笔记2:串口通信

今日开始快速掌握这款STM32F103RCT6芯片的环境与编程开发&#xff0c;有关基础知识的部分不会多唠&#xff0c;直接实践与运用&#xff01;文章贴出代码测试工程与测试效果图&#xff1a; 目录 串口通信实验计划&#xff1a; 串口通信配置代码&#xff1a; 测试效果图&#…

2007-2021年31省市财政环保支出占比数据(含原始数据+计算过程+测算结果)

2007-2021年31省市财政环保支出占比数据&#xff08;含原始数据计算过程测算结果&#xff09; 1、时间&#xff1a;2007-2021年 2、来源&#xff1a;整理自国家统计局和统计年鉴 3、指标&#xff1a;财政环境保护支出、财政一般预算支出、环保支出占比 4、计算公式&#xf…

【jmeter】jmeter引用变量,变量值传递失败

最近在用jmeter做接口测试的时候&#xff0c;发现有个变量&#xff0c;参数值一直没有传递进来&#xff0c;导致request的时候&#xff0c;请求体里面一直是${}变量的形式。 后来经过排查发现&#xff0c;是因为我在定义用户变量的时候&#xff0c;在这个now后面多加了一个空格…

leetcode25 K个一组反转链表

题目 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节点内部…