【Leetcode】 94. 二叉树的中序遍历

news2024/11/18 1:37:59

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

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

示例 2

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

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

提示

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

进阶: 递归算法很简单,你可以通过迭代算法完成吗?


AC:

/*
 * @lc app=leetcode.cn id=94 lang=cpp
 *
 * [94] 二叉树的中序遍历
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while(cur || !st.empty()) {
            if(cur) {
                st.push(cur);
                cur = cur->left;
            }
            else {
                cur = st.top();
                st.pop();
                res.push_back(cur->val);
                cur = cur->right;
            }
        }
        return res;
    }
};
// @lc code=end

res

着重谈一下 Morris 遍历
AC

/*
 * @lc app=leetcode.cn id=94 lang=cpp
 *
 * [94] 二叉树的中序遍历
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
/*
    Morris 遍历中,需要利用前驱节点指向当前节点的方式来遍历二叉树,
    算法的核心思想是将二叉树中每个节点的前驱节点的右孩子指向该节点,
    这样在遍历完当前节点的左子树后,
    可以通过前驱节点的右孩子指针找到该节点,
    并且不需要再次遍历该节点的左子树。遍历完成后,
    需要将前驱节点的右孩子指针重置为空。
*/
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
    // 定义结果数组和前驱节点指针
    vector<int> res;
    TreeNode *predecessor = nullptr;
    // 循环迭代直到遍历完整个二叉树
    while(root)
    {
        // 如果当前节点有左子节点,需要找到其左子树的最右侧节点作为前驱节点
        if(root->left)
        {
            // 找到前驱节点
            predecessor = root->left;
            while(predecessor->right && predecessor->right != root)
                predecessor = predecessor->right;
            // 如果前驱节点的右孩子为空,则将前驱节点的右孩子指向当前节点,然后遍历左子树
            if(predecessor->right == nullptr)
            {
                predecessor->right = root;
                root = root->left;
            }
            // 如果前驱节点的右孩子指向当前节点,说明左子树已经遍历完成,将前驱节点的右孩子置为空,并将当前节点加入结果数组,然后遍历右子树
            else{
                res.push_back(root->val);
                predecessor->right = nullptr;
                root = root->right;
            }
        }
        // 如果当前节点没有左子节点,则将当前节点加入结果数组,然后遍历右子树
        else{
            res.push_back(root->val);
            root = root->right;
        }
    }
    // 返回结果数组
    return res;
    }
};
// @lc code=end

Morris遍历是一种使用线索二叉树进行遍历的算法,它的空间复杂度O(1)。以下是C++代码实现:

前序遍历

void morrisPreorderTraversal(TreeNode* root) {
    if (!root) return;
    TreeNode* cur = root, *predecessor = nullptr;
    while (cur) {
        if (!cur->left) {
            cout << cur->val << " ";
            cur = cur->right;
        }
        else {
            predecessor = cur->left;
            while (predecessor->right && predecessor->right != cur) {
                predecessor = predecessor->right;
            }
            if (!predecessor->right) {
                cout << cur->val << " ";
                predecessor->right = cur;
                cur = cur->left;
            }
            else {
                predecessor->right = nullptr;
                cur = cur->right;
            }
        }
    }
}

中序遍历:

void morrisInorderTraversal(TreeNode* root) {
    if (!root) return;
    TreeNode* cur = root, *predecessor = nullptr;
    while (cur) {
        if (!cur->left) {
            cout << cur->val << " ";
            cur = cur->right;
        }
        else {
            predecessor = cur->left;
            while (predecessor->right && predecessor->right != cur) {
                predecessor = predecessor->right;
            }
            if (!predecessor->right) {
                predecessor->right = cur;
                cur = cur->left;
            }
            else {
                predecessor->right = nullptr;
                cout << cur->val << " ";
                cur = cur->right;
            }
        }
    }
}

后序遍历:

vector<int> morrisPostorderTraversal(TreeNode* root) {
    if (!root) return {};
    vector<int> res;
    TreeNode* cur = root, *predecessor = nullptr;
    while (cur) {
        if (!cur->right) {
            res.push_back(cur->val);
            cur = cur->left;
        }
        else {
            predecessor = cur->right;
            while (predecessor->left && predecessor->left != cur) {
                predecessor = predecessor->left;
            }
            if (!predecessor->left) {
                res.push_back(cur->val);
                predecessor->left = cur;
                cur = cur->right;
            }
            else {
                predecessor->left = nullptr;
                cur = cur->left;
            }
        }
    }
    reverse(res.begin(), res.end());
    return res;
}

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

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

相关文章

低代码PAAS加速推进企业数字化转型

无论是“十四五”规划从国家层面提出的“加快数字化发展 建设数字中国”&#xff0c;还是后疫情时代企业自身的感受&#xff0c;数字化转型已成为必答题。当前 企业 业务场景化、线上趋势愈加明显&#xff0c;越来越多并发的数字化应用场景&#xff0c;而原有集中式架构扩展能力…

图片去除水印文字怎么去除?这几个方法快来收藏

图片怎么去除水印文字&#xff1f;现在嘛&#xff0c;图片已经成了我们生活和工作里必不可少的一部分&#xff0c;可是有时候看图的时候&#xff0c;总会碰到一些带水印的图片&#xff0c;这些水印总是搞得图片看起来不那么爽&#xff0c;所以很多人都想知道图片怎么去除水印文…

力扣:145. 二叉树的后序遍历(Python3)

题目&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 示例&#xff1a; 示例 1&#xff1…

快速了解ClickHouse!

简介 ClickHouse是一个开源列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;用于在线分析处理&#xff08;OLAP&#xff09;&#xff1a; 列式存储&#xff1a;与传统的行式数据库不同&#xff0c;ClickHouse以列的形式存储数据&#xff0c;这使得在分析大量数据时…

3.1、Linux开发工具之vim编辑器

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 前言&#xff1a; 插入模式 底行模式 命令模式 前言&#xff1a; 没有进行配置的vim编辑器在写代码时和记事本没什么两样&#xff0c;所以最开始我们可以先下载一个插件&#xff0c;在Linux下两行指令的问题&…

表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信你对这篇博客也感兴趣o (ˉ▽ˉ&#xff1b;) 用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证&#xff08;带前后端源码&#xff09;全方位全流程超详细教程 目录 项目前端页面展…

十种排序算法(1) - 准备测试函数和工具

1.准备工作 我们先写一堆工具&#xff0c;后续要用&#xff0c;不然这些写在代码里可读性巨差 #pragma once #include<stdio.h>//为C语言定义bool类型 typedef int bool; #define false 0 #define true 1//用于交互a和b inline void swap(int* a, int* b) {/*int c *a…

Kibana无法启动 kibana_task_manager search_phase_execution_exception 问题解决

今天服务器重启以后&#xff0c;发现无法启动Kibana服务了&#xff0c;在网上也是把错误搜索了半天&#xff0c;尝试了那些命令&#xff0c;但是执行删除命令时居然报错了。后来&#xff0c;仔细观察后&#xff0c;发现是删除方式不太正确&#xff0c;需要改一下删除命令才能正…

Java on Azure Tooling 9月更新|Azure OpenAI 服务和 Playground 支持及更多

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 开发者工具九月份更新。在本次更新中&#xff0c;我们将介绍对 Azure OpenAI 服务和 Playground 的支持&#xff0c;开发…

python创建个人交易策略

编写您的第一个交易策略的综合教程。 介绍 创建个人交易策略在家庭交易者和/或 Python 爱好者中变得越来越流行。本文将介绍交易策略的完整生命周期:从获取市场数据开始,计算技术指标,生成交易信号,最后评估策略的有效性。 我们将使用 Kraken API 中的美元 价格,并基于移…

Vue 报错error:0308010C:digital envelope routines::unsupported

export NODE_OPTIONS--openssl-legacy-provider linux 可以解决

dbeaver配置es连接org.elasticsearch.xpack.sql.jdbc.EsDriver

查看目标es服务版本&#xff0c;下载对应驱动

GEO生信数据挖掘(十一)STRING数据库PPI蛋白互作网络 Cytoscape个性化绘图【SCI 指日可待】

GEO生信数据挖掘&#xff08;十&#xff09;肺结核数据-差异分析-WGCNA分析&#xff08;900行代码整理注释更新版本&#xff09; 通过 前面十篇文章的学习&#xff0c;我们应该已经可以获取到一个”心仪的基因列表“了&#xff0c;相较于原始基因数量&#xff0c;这个列表的数…

解决方案|法大大电子合同加速互联网家装服务升级

随着互联网的快速发展以及政策的不断推动&#xff0c;家装行业“互联网”趋势也不断凸显。行业内很多企业已经开始在全链条业务中使用电子合同&#xff0c;基于电子合同合规化、无纸化、线上化、智能化的价值赋能&#xff0c;实现家装从需求沟通、家装设计、选材、装修施工、验…

如何在mac 安装 cocos 的 android环境

基本概念&#xff1a; Java: Java 是一种编程语言&#xff0c;由Sun Microsystems&#xff08;现在是 Oracle Corporation&#xff09;开发。Java 是一种跨平台的语言&#xff0c;可以用于开发各种应用程序&#xff0c;包括 Android 应用程序。Android 应用程序的核心代码通常用…

会声会影2024永久激活序列号密钥 CDR Keygens 2024通用注册机

Corel All Products Universal Keygens 2024通用注册机是一款非常实用的激活工具&#xff0c;专门用于激活Corel全系列产品。尤其是被广泛使用的CorelDRAW作图软件和Corel VideoStudio会声会影视频编辑处理软件。小编也是一直关注由X-Force团队制作的注册机&#xff0c;目前已更…

Vue中动态增加表单项的方法

<!-- 需求 1 根据点击添加 生成表格数据 2 动态添加 表单-->点击添加生成对应动态表单 HTML <template><div class"main"><!-- 动态添加 --><div v-for"(item, index) in dataResult" :key"index"><a-form-mo…

Swagger + DOCWAY 一步导出为优雅完整的Markdown、Pdf接口文档

只要开发&#xff0c;只要写接口应该没人不知道Swagger&#xff0c;但DOCWAY可能知道的人不多&#xff0c;但知道用过后就离不开了&#xff0c;不管是作为多方联调的接口文档&#xff0c;还是交接给客户的文档&#xff0c;都是可以的&#xff0c;具体如何使用&#xff0c;详细步…

评估在线不平衡学习的PAUC

评估在线不平衡学习的PAUC 原始论文《Prequential AUC: properties of the area under the ROC curve for data streams with concept drift》 由于正常的AUC需要计算整体数据集上&#xff0c;每个数据的预测置信度的排名。那么我们首先要求我们的在线学习算法在进行预测时也返…

Vue的动画与过度

一、Vue的动画效果 &#xff08;一&#xff09;编写CSS关键帧动画 keyframes show{from{transform: translateX(-100%);}to{transform: translateX(0px);} } &#xff08;二&#xff09;定义动画效果 .v-enter-active { animation: 配置项 } // 显示动画 .v-leave-active…