C# 二叉树的后序遍历

news2024/11/17 17:37:35

145 二叉树的后序遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

示例 1:

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

输入:root = []
输出:[]
示例 3:

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

提示:

树中节点的数目在范围 [0, 100] 内
-100 <= Node.val <= 100

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

解决方案:

提供思路

1)二叉树的后序遍历的方法为:依次遍历左子树、右子树和根结点,对于左子树和右子树使用同样的方法遍历。由于遍历过程具有递归的性质,因此可以使用递归的方法实现二叉树的后序遍历。

递归的终止条件是当前结点为空。对于非终止条件,递归的做法如下。

1.对当前结点的左子树调用递归。

2.对当前结点的右子树调用递归。

3.将当前结点的结点值加入后序遍历序列。

遍历结束之后即可得到后序遍历序列。

2)使用迭代的方法实现二叉树的后序遍历,则需要使用栈存储结点。

相比于前序遍历和中序遍历,后序遍历的迭代较为复杂。由于后序遍历对于每个子树都是最后访问根结点,因此需要记录上一个访问的结点,才能确保不会重复访问同一个结点。

从根结点开始遍历,遍历的终止条件是栈为空且当前结点为空。遍历的做法如下。

如果当前结点不为空,则将当前结点入栈,然后将当前结点移动到其左子结点,重复该操作直到当前结点为空。

将当前结点设为栈顶结点,判断其右子结点是否为空以及是否为上一个访问的结点。

1.如果当前结点的右子结点不为空且不为上一个访问的结点,则将当前结点移动到其右子结点。

2.如果当前结点的右子结点为空或者为上一个访问的结点,则将当前结点出栈,将当前结点的结点值加入后序遍历序列,将上一个访问的结点设为当前结点,将当前结点设为空。

3.重复上述操作,直到达到遍历的终止条件。

3)莫里斯遍历是使用常数空间遍历二叉树的方法,由 J. H. Morris 提出。莫里斯遍历的核心思想是利用二叉树的空闲指针维护遍历顺序,达到省略栈空间的目的。

相比于前序遍历和中序遍历,后序遍历的莫里斯遍历较为复杂。

从根结点开始遍历,遍历的终止条件是当前结点为空。

1.对于每个结点,判断当前结点的左子树是否为空,执行相应的操作。

如果当前结点的左子树为空,则将当前结点移动到其右子结点。

如果当前结点的左子树不为空,则找到当前结点的前驱结点,前驱结点为当前结点的左子树中的最右边的结点,判断前驱结点的右子结点是否为空。

如果前驱结点的右子结点为空,则将前驱结点的右子结点设为当前结点,将当前结点移动到其左子结点。

如果前驱结点的右子结点不为空,则将前驱结点的右子结点设为空,将当前结点的左子结点至当前结点的前驱结点的路径上的所有结点的结点值倒序加入后序遍历序列,将当前结点移动到其右子结点。

2.重复上述操作,直到达到遍历的终止条件。最后将根结点的结点值加入后序遍历序列。

上代码:

//1
public class Solution
{
    IList<int> traversal = new List<int>();

    public IList<int> PostorderTraversal(TreeNode root)
    {
        Postorder(root);
        return traversal;
    }

    public void Postorder(TreeNode node)
    {
        if (node == null)
        {
            return;
        }
        Postorder(node.left);
        Postorder(node.right);
        traversal.Add(node.val);
    }
}

//2
public class Solution
{
    public IList<int> PostorderTraversal(TreeNode root)
    {
        IList<int> traversal = new List<int>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode node = root, prev = null;
        while (stack.Count > 0 || node != null)
        {
            while (node != null)
            {
                stack.Push(node);
                node = node.left;
            }
            node = stack.Peek();
            if (node.right != null && node.right != prev)
            {
                node = node.right;
            }
            else
            {
                stack.Pop();
                traversal.Add(node.val);
                prev = node;
                node = null;
            }
        }
        return traversal;
    }
}

//3
public class Solution
{
    public IList<int> PostorderTraversal(TreeNode root)
    {
        IList<int> traversal = new List<int>();
        TreeNode node = root;
        while (node != null)
        {
            if (node.left == null)
            {
                node = node.right;
            }
            else
            {
                TreeNode predecessor = node.left;
                while (predecessor.right != null && predecessor.right != node)
                {
                    predecessor = predecessor.right;
                }
                if (predecessor.right == null)
                {
                    predecessor.right = node;
                    node = node.left;
                }
                else
                {
                    predecessor.right = null;
                    AddToTraversal(node.left, traversal);
                    node = node.right;
                }
            }
        }
        AddToTraversal(root, traversal);
        return traversal;
    }

    public void AddToTraversal(TreeNode node, IList<int> traversal)
    {
        int size1 = traversal.Count;
        while (node != null)
        {
            traversal.Add(node.val);
            node = node.right;
        }
        int size2 = traversal.Count;
        int left = size1, right = size2 - 1;
        while (left < right)
        {
            int val1 = traversal[left], val2 = traversal[right];
            traversal[left] = val2;
            traversal[right] = val1;
            left++;
            right--;
        }
    }
}

以上是碰到的第一百四十五题,后续持续更新。感觉对你有帮助的小伙伴可以帮忙点个赞噢!
在这里插入图片描述

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

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

相关文章

php未定义索引数组怎么解决

在PHP中&#xff0c;如果使用一个未定义的数组索引&#xff0c;就会出现未定义索引错误。在这种情况下&#xff0c;需要采取措施解决这个问题。本文将为您介绍几种解决php未定义索引数组的方法。 1.使用isset()函数检查数组索引是否存在 使用函数isset()可以检查一个变量是否…

A股股民调查:58%股民表示“亏惨了”

A股上半年赚钱效应究竟如何&#xff1f; 东方财富网的一份调查显示&#xff0c;有58%的股民表示今年上半年亏惨了&#xff0c;另有9%的股民略有浮亏。 成交“先冷后热”、基金发行遇冷 A股的上半年已正式收官&#xff01;A股三大指数上半年涨跌不一&#xff0c;其中沪指累涨…

希尔排序(C语言)

希尔排序 一、希尔排序的原理二、动图演示三、代码实现四、实现从小到大排序五、希尔排序的优缺点 一、希尔排序的原理 希尔排序是插入排序的一种更高效的改进版本。 1.将原始待排数据按照设定的增量gap分成多组&#xff0c;每组有n / gap个元素。 2.对这些分组进行插入排序&a…

Linux 学习记录43(C++篇)

Linux 学习记录43(C篇) 本文目录 Linux 学习记录43(C篇)一、友元1. 友元函数(1. 全局函数作为友元函数(2. 类中的成员函数作为友元 2. 友元类3. 友元的注意事项 二、常成员函数和常对象(const)1.常成员函数2. 常对象3. mutable 关键字 三、运算符重载1. 常见的运算符2. 运算符重…

【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记

目录 一、概述二、main 函数解析三、main_inner 函数解析四、sample_audio_ai_ao 函数解析4.1 Audio Codec相关配置 五 一、概述 上篇文章 【海思SS528】MPP媒体处理软件V5.0 | 音频模块 - 学习笔记 学习了海思MPP媒体处理平台的一小部分音频知识&#xff0c;这篇文章继续学习与…

(5)深度学习学习笔记-多层感知机

文章目录 多层感知机和激活函数代码来源 多层感知机和激活函数 通过在网络中加入一个或多个隐藏层来克服线性模型的限制&#xff0c;使其能处理更普遍的函数关系类型。最简单的方法是将多个全连接层堆叠在一起。每一层都输出到上面的层&#xff0c;直到生成最后的输出&#xf…

Android12之ServiceManager::addService添加服务的本质(一百五十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

Python-创建虚拟环境并指定环境目录

1.简介 程序运行依赖于环境&#xff0c;不同程序依赖的环境不尽相同。如果一个项目依赖于一个第三方库的1.0版本&#xff0c;另一个项目依赖于这个第三方库的2.0版本&#xff0c;在一个python环境中一个库只能同时存在一个版本&#xff0c;所以就产生了版本冲突。虚拟环境就是为…

git 显示不出图标

今天写完代码准备上传 gitee 的时候发现&#xff0c;自己的本地文件夹没有小绿勾了&#xff0c;整的我一时分不清到底哪些文件已经上传过。 研究了半天终于搞定了&#xff0c;现在把方法记录下来&#xff0c;防止以后继续出现这种问题还要找半天。 1. 打开注册表 win R 打开运…

【Python 随练】按键变色

题目&#xff1a; Press any key to change color, do you want to try it. Please hurry up! 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个编程问题&#xff1a;按下任意键改变颜色。我们将提供一个完整的代码示例来实现这个功能&#xff0c;并鼓励读者尝试。…

亚马逊云科技自研芯片,为企业云服务提高性价比

6月27日至28日&#xff0c;2023亚马逊云科技中国峰会于上海顺利召开。在本次峰会上&#xff0c;似乎找寻到了云计算领域竞争对手均日渐成熟&#xff0c;而亚马逊云科技却能一直保持领先地位的原因——过去的十几年里&#xff0c;亚马逊云科技“基于客户需求&#xff0c;快速进行…

gnutls_handshake() failed: The TLS connection was non-properly terminated.

从远程仓库获取所有更新&#xff0c;并保存在本地时&#xff0c;使用git fetch 命令时出现如下错误&#xff1a; 解决办法&#xff1a; 问题解决&#xff1a; 参考资料 拉取github报错 gnutls_handshake() failed: The TLS connection was non-properly terminated. git获取…

proteus三级管(NPN)仿真LED灯串的开关

实验里设置LED灯的导通电压为1.2V 打开仿真开关后可以看到&#xff0c;此时三极管不导通&#xff0c;LED灯亮了&#xff0c;并且电压表和电流探针有数值显示 按下按键&#xff0c;三级管导通&#xff0c;LED灯灭

Spring MVC相关注解运用 —— 上篇

目录 一、Controller、RequestMapping 1.1 示例程序 1.2 测试结果 二、RequestParam 2.1 示例程序 2.2 测试结果 三、RequestHeader、CookieValue 3.1 示例程序 3.2 测试结果 四、SessionAttributes 4.1 示例程序 4.2 测试结果 五、ModelAttribute 5.1 示例程序 …

4G/wifi/lora投入式无线液位传感变送器 mqtt/http协议对接云平台

1.产品概述 DAQ-GP-TLL4G无线液位传感器终端是上海数采物联网科技有限公司推出的一款无线液体水位测量产品。原理是利用扩散硅片上的一个惠斯通电桥&#xff0c;被测介质&#xff08;气体或液体&#xff09;施压使桥壁电阻值发生变化&#xff08;压阻效应&#xff09;&#xff…

A_B_C滑块

分享一个有意思的滑块。 网址:https://xxgs.chinanpo.mca.gov.cn/gsxt/newList 图片好看,不知道说啥了,验证部分。 ok,源码在这,自提。 # -*- coding:utf-8 -*- # author: qinshaowen # V:15702312233 import requests,base64 import execjs,ddddocr from loguru impo…

Springboot 集成Prometheus 数据采集 使用grafana 监控报告告警 邮件配置

目录 Springboot 相关 Pom 重点包 如果有需要可以增加安全包-一般内部机房没啥事-&#xff08;非必选&#xff09; Application.yml配置文件-&#xff08;非必选&#xff09; Application.properties management.endpoints.web.exposure.include介绍 启动类 查看监控信…

[RocketMQ] Producer发送单向/异步/同步消息源码 (八)

文章目录 1.sendMessage方法发送消息2.invokeOneway单向发送2.1 invokeOnewayImpl单向调用 3.sendMessageSync同步发送3.1 invokeSync同步调用3.1.1 invokeSyncImpl同步调用实现3.1.2 processSendResponse处理响应结果 4.sendMessageAsync异步发送消息4.1 invokeAsync异步调用4…

信号链噪声分析16

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 上世纪 50、60 年代&#xff0c;积分非线性度、差分非线性度、单调性、无失码、增益误差、 失调误差、漂移等直流性能规格主要用于表示数据转换器的性能特性。在当时&#xff0…

【企业架构框架】SOGAF 运营模式

Salesforce 运营、治理和架构框架 (SOGAF) 将 MIT-CISR 企业架构框架应用于 Salesforce 实施和程序。 介绍 运营模式有两个维度&#xff1a;业务流程标准化和业务流程集成。业务流程和相关系统的标准化意味着准确定义流程的执行方式。运营模式可提高整个公司的效率和可预测性。…