二叉树的非递归与相关oj

news2024/11/15 10:44:38

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述

文章目录

  • 一、二叉树相关oj
    • ①二叉搜索树与双向链表
    • ②前序遍历和中序遍历构造二叉树
  • 二、二叉树的非递归
    • ①前序遍历非递归
    • ②中序遍历非递归
    • ③后序遍历非递归

一、二叉树相关oj

①二叉搜索树与双向链表

二叉搜索树与双向链表链接
在这里插入图片描述
根据上一章搜索二叉树我们可以发现,这是搜索二叉树的中序遍历特性,所以也就是要我们对这棵树进行中序遍历,并链接起来
思路:我们可以想象它已经是遍历好的结果,我们只是对它的左右指针进行一点调节,利用递归来进行整棵树进行递归(可以认为是已经构建好了的双向链表,但是指向出了点问题,我们要通过对树的中序遍历这种方式来顺序访问到双向链表中的各个结点来修改指向)

class Solution {
public:
	TreeNode*prev=nullptr;
	TreeNode*head=nullptr;
    TreeNode* Convert(TreeNode* pRootOfTree) {
		if(pRootOfTree==nullptr) return nullptr;
		Convert(pRootOfTree->left);//找到头
		pRootOfTree->left = prev;
		if(prev) prev->right = pRootOfTree;
		prev = pRootOfTree;//前指针后移
		head = head==nullptr?pRootOfTree:head;//空的话就找这个头,不然就不变
		Convert(pRootOfTree->right);//继续遍历,代表想象链表后移
		return head;
    }
};

②前序遍历和中序遍历构造二叉树

前序遍历和中序遍历构造二叉树链接
在这里插入图片描述
从前序遍历和中序遍历的特性中我们可以看出,前序遍历 先访问根结点,再访问左子树 ,再访问右子树,中序遍历 先访问左子树,再访问根结点,再访问右子树 ,所以我们可以通过前序遍历来找到中序遍历的左子树和右子树

/**
 * 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:
    int move=0;
    TreeNode*buildTreeHelper(vector<int>&preorder,vector<int>&inorder,int start,int finish)
    {
        if(start>=finish)
        return nullptr;
        int target=0;
        for(int i=start;i<finish;i++)
        {
            if(preorder[move]==inorder[i])
            {
                target=i;
                move++;//找每一个根
                break;
            }
        }
        TreeNode* ret =  new TreeNode(inorder[target]);
        ret ->left = buildTreeHelper(preorder,inorder,start,target);//构造左树,左闭右开区间
        ret ->right = buildTreeHelper(preorder,inorder,target+1,finish);//构造右树
        return ret;        
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0) return nullptr;
        return buildTreeHelper(preorder,inorder,0,preorder.size());//构造
    }
};

二、二叉树的非递归

①前序遍历非递归

借助一个栈,一直遍历左树,并放进栈和返回的数组,当没有左时,就取出栈的top(),拿到该结点的右子树的根结点,然后重复上述操作,前序遍历的特点就是优先遍历根,再左树,再右树
二叉树的前序遍历非递归

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> ret;
        if(root==nullptr) return ret;
        st.push(root);
        TreeNode*cur= st.top();
        while(!st.empty())  
        {
            while(cur)
            {
                ret.push_back(cur->val);
                st.push(cur);
                cur=cur->left;  
            }
            TreeNode*tmp= st.top();
            st.pop();
            if(tmp&&tmp->right) 
            {
                cur = tmp->right;
            }
        }
        return ret;
    }
};

②中序遍历非递归

中序遍历的特点就是先访问左子树再访问根再访问右子树,把前序遍历稍微变一变即可,比如先入栈,等左子树入栈完了,开始从栈中取top,此时再去入返回数组,所以直接去遍历右子树一样的操作即可

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> ret;
        if(root==nullptr) return ret;
        st.push(root);
        TreeNode*cur= root->left;
        while(cur||!st.empty())  
        {
            while(cur)
            {
                st.push(cur);
                cur=cur->left;  
            }
            TreeNode*tmp= st.top();
            ret.push_back(tmp->val);
            st.pop();
            if(tmp&&tmp->right) 
            {
                cur = tmp->right;
            }
        }
        return ret;
    }
};

③后序遍历非递归

后序遍历的特点是先访问右子树,再访问左子树,再访问根,通过一个prev来存储上一次遍历的结点,来判断是否需要往右遍历,避免死循环

/**
 * 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> postorderTraversal(TreeNode* root) {
        //根右左,再逆序
         stack<TreeNode*> st;
        vector<int> ret;
        if(root==nullptr) return ret;
        st.push(root);
        TreeNode*cur= root->left;
        TreeNode*prev=nullptr;
        while(!st.empty())  
        {
            while(cur)
            {
                st.push(cur);
                cur=cur->left;  
            }
            TreeNode*tmp = st.top();
            if(tmp->right==nullptr||tmp->right==prev)
            {
                ret.push_back(tmp->val);
                prev=tmp;//prev就是遍历该结点时的上一个结点
                st.pop();
            }
            else
            {
                cur= tmp->right;//直到返回到有右结点并没有遍历过的时候cur才发挥作用,不然又会去遍历左树
            }
        }
        return ret;
    }
};

在这里插入图片描述

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

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

相关文章

简单的算法思想 - 利用快慢指针解决问题 - 寻找链表中的中间节点,回文序列,倒数第k个节点 - 详解

文章目录1. 寻找链表中倒数第K个节点1.1. 思路分析1.2 代码实现2. 寻找链表中的中间结点2.1 思路概述2.2 代码实现3. 链表的回文结构3.1 思路分析3.2 代码实现总结✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来&#xff01; 本文通过寻找链表中的中间节点&#xff0…

汽车托运网址

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 基于Web的汽车托运网站的设计与实现 网站前台&#xff1a;关于我们、联系我们、公告信息、卡车类型、卡车信息、运输评论…

【语音处理】一种增强的隐写及其在IP语音隐写中的应用(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Effective Objective-C 2.0学习记录(一)

48.多用块枚举&#xff0c;少用for循环for循环快速枚举&#xff08;快速遍历&#xff09;基于块的遍历方式在编程中经常需要用到列举collection&#xff08;NSArray、NSDictionary、NSSet等&#xff09;中的元素&#xff0c;当前的Objective-C语言有多种办法实现此功能&#xf…

【专栏】核心篇09| 怎么保证缓存与DB的数据一致性

计算机类PDF整理&#xff1a;【详细&#xff01;&#xff01;】计算机类PDF整理 Redis专栏合集 【专栏】01| Redis夜的第一章 【专栏】基础篇02| Redis 旁路缓存的价值 【专栏】基础篇03| Redis 花样的数据结构 【专栏】基础篇04| Redis 该怎么保证数据不丢失&#xff08;上…

Python -- 模块和包

目录 1.Python中的模块 1.1 import 1.3 from...import * 1.4 as别名 2.常见的系统模块和使用 2.1 OS模块 2.2 sys模块 2.3 math模块 2.4 random模块 2.5 datetime模块 2.6 time模块 2.7 calendar模块 2.8 hashlib模块 2.9 hmac模块 2.10 copy模块 3.pip命令的使…

【机器学习---01】机器学习

文章目录1. 什么是机器学习&#xff1f;2. 机器学习分类2.1 基本分类2.2 按模型分类2.3 其他分类(不重要)3. 机器学习三要素4. 监督学习的应用(分类、标注、回归问题)1. 什么是机器学习&#xff1f; 定义&#xff1a;给定训练集D&#xff0c;让计算机从一个函数集合F {f1(x)&…

虚拟机打不开,提示“此主机不支持虚拟化实际模式”的详细解决方法

虚拟机打不开&#xff0c;提示“此主机不支持虚拟机实际模式”的解决方法 一、第一种情况安装/启动虚拟机失败&#xff0c; 在VMWare软件中&#xff0c;安装/启动虚拟机时&#xff0c;如果出以类似以下的错误提示&#xff1a; 出现该提示是由于电脑不支持虚拟化技术或是相关功…

IDEA报错:类文件具有错误的版本 61.0,应为52.0

springboot项目启动报错&#xff1a; 类文件具有错误的版本 61.0,应为52.0 请删除该文件或确保该文件位于正确的类路径子目录中 查阅了网上的很多资料&#xff0c;普遍原因说是springboot版本过高&#xff0c;高于3.0 需要在pom文件中降低版本 也有说是idea的maven配置java版…

网购商城网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

【Python机器学习】层次聚类AGNES、二分K-Means算法的讲解及实战演示(图文解释 附源码)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 层次聚类 在聚类算法中&#xff0c;有一类研究执行过程的算法&#xff0c;它们以其他聚类算法为基础&#xff0c;通过不同的运用方式试图达到提高效率&#xff0c;避免局部最优等目的&#xff0c;这类算法主要有网格聚类和…

easypoi导入excel空指针异常

问题描述 前端页面停留在导入页面&#xff0c;通过后端返回的接口&#xff0c;确认后端已经抛出异常查看系统调用错误日志为 java.lang.NullPointerException: nullat org.apache.poi.xssf.usermodel.XSSFClientAnchor.setCol2(XSSFClientAnchor.java:231)at org.apache.poi.…

基于EKF的四旋翼无人机姿态估计matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 卡尔曼滤波是一种高效率的递归滤波器(自回归滤波器)&#xff0c;它能够从一系列的不完全包含噪声的测量中&#xff0c;估计动态系统的状态。这种滤波方法以它的发明者鲁道夫E卡尔曼&#xff08;R…

Android koin

1.源码地址 1.源码地址 2.作用 1.让代码看起来更简洁 现在是这样创建对象的 2.解耦 我们有一个类&#xff0c;然后有100个地方使用它&#xff0c;这个时候如果我们要修改构造参数&#xff0c;加入一个参数&#xff0c;那么我们就要修改100个地方&#xff1b;如果过了一个…

怎样让chatGPT给你打工然后月入过千?

前言 chatGPT最近火出圈了&#xff0c;怎么薅一个文字模型给你打工呢&#xff1f; 这个UP给了个思路&#xff1a;哔哩哔哩 emmm有点尴尬&#xff0c;可能是热度比较高&#xff0c;b站的视频作者自己下架了。 总结一下&#xff1a; 薅的对象百度文库创作中心&#xff1a;地址…

设计模式之装饰器模式

decorator design pattern 装饰模式的概念、装饰模式的结构、装饰模式的优缺点、装饰模式的使用场景、装饰模式与代理模式的区别、装饰模式的实现示例、装饰模式的源码分析 1、装饰模式的概念 装饰模式&#xff0c;即在不改变现有对象结构的前提下&#xff0c;动态的给对象增加…

【云原生】Grafana 介绍与实战操作

文章目录一、概述二、Grafana 安装1&#xff09;下载安装2&#xff09;安装包信息3&#xff09;启动服务4&#xff09;Grafana 访问三、Grafana 功能介绍四、使用mysql存储1&#xff09;安装mysql2&#xff09;修改grafana配置1、创建grafana用户和grafana库2、修改grafana配置…

[附源码]Python计算机毕业设计Django学分制环境下本科生学业预警帮扶系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Innodb存储引擎-索引和算法(B+树索引、Cardinality、联合索引、覆盖索引、MRR优化、ICP优化、哈希索引、全文索引)

文章目录索引和算法B树索引聚集索引辅助索引B 树索引的分裂B 树索引的管理Cardinality 值B 树索引的使用联合索引覆盖索引优化器选择不使用索引的情况索引提示Multi-Range Read 优化(MRR)Index Condition Pushdown优化(ICP)哈希索引全文索引倒排索引InnoDB全文检索的实现全文检…

第一个MyBatis查询

⭐️前言⭐️ 在连接程序与数据库的工具中&#xff0c;我们之前使用的是JDBC技术&#xff0c;但是JDBC的操作流程极为繁琐&#xff0c;因此才有了更优秀框架——MyBatis&#xff0c;下边我们一起来看这个优秀框架MyBatis的操作与使用。 &#x1f349;欢迎点赞 &#x1f44d; 收…