二叉树的前 中 后序的非递归实现(图文详解)

这篇具有很好参考价值的文章主要介绍了二叉树的前 中 后序的非递归实现(图文详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻强烈推荐优质专栏: 🍔🍟🌯C++的世界(持续更新中)
🐻推荐专栏1: 🍔🍟🌯C语言初阶
🐻推荐专栏2: 🍔🍟🌯C语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:非递归实现二叉树的前中后序遍历.
金句分享:
✨不要慌,不要慌,太阳下了,有月光!✨

前言

为什么要掌握非递归呢?
递归实现前中后序遍历十分轻松,二非递归就复杂许多了.

主要是递归有以下几个缺陷:

  1. 内存消耗:递归算法由于会在堆栈中不停地压入和弹出函数调用记录,因此会占用大量的内存,如果递归的次数过多,可能会导致栈溢出。

  2. 效率低下:递归算法的效率低下,因为每次递归都需要重新压入调用记录和恢复上一次的状态,这些操作都会增加额外的开销,导致递归算法效率低下,特别是在处理大量数据时会更为明显。

  3. 可读性较差:递归算法的代码一般会比较复杂,理解和维护难度较大,而且递归算法往往涉及到栈的使用,在理解和分析时需要一定的数学基础。

总结:主要害怕栈溢出,其次,可以增加一点点效率.

一、非递归实现"前序遍历"

题目链接:传送门

题目要求:
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

补充知识:
二叉树的前序遍历,又称为先序遍历,是指先访问节点本身,然后按照先左后右的顺序遍历其左右子树。具体步骤如下:

  1. 访问根节点。
  2. 遍历左子树,即对左子节点进行前序遍历。
  3. 遍历右子树,即对右子节点进行前序遍历。

方法一、思路分析:

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode

  1. 根节点入栈.
  2. 栈顶元素入存入vector,根节点出栈.
  3. 右孩子入栈
  4. 左孩子入栈

因为我们要求:
先访问左孩子,再访问右孩子.
后进先出的结构,所以:
右孩子先入栈,左孩子后入栈.

步骤示例图:
二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode(图片为博主:"初阶牛"原创,未经允许,不得复制)

结果:
二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode

🍔非递归代码实现1:

 class Solution {
 public:
     vector<int> preorderTraversal(TreeNode* root) {
         stack<TreeNode*> s1;
         vector<int> v1;
         s1.push(root);//根节点先入栈

         while (!s1.empty()) {				//当栈为空时,结束
            TreeNode* top = s1.top();
            if(top==nullptr)break;
            v1.push_back(top->val);			//出栈前,先将栈顶元素存入vector

             //栈顶元素出栈
            s1.pop();
             //栈顶元素的右左子树入栈
            if (top->right)
                 s1.push(top->right);
            if (top->left)
                 s1.push(top->left);
         }
         return v1;
     }
 };

方法二、思路分析

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode

  1. 左路节点一边存入vector,一边入栈.
  2. 栈顶元素出栈,如果栈顶元素有右子树,则将右子树转化为子问题,和步骤1一样.

注意循环的结束条件.

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode(图片为博主:"初阶牛"原创,未经允许,不得复制)

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode
(图片为博主:"初阶牛"原创,未经允许,不得复制)

🍉非递归实现2:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> v1;
        stack<TreeNode*> s1;
        TreeNode* cur=root;
        while(cur || !s1.empty()){
            //将左路节点全部存入栈
            while(cur){
                v1.push_back(cur->val);
                s1.push(cur);
                cur=cur->left;
            }
            //栈顶元素出栈
            TreeNode*top=s1.top();
            s1.pop();
			//如果栈顶元素的右子树存在,则转化为子问题解决.
            if(top->right)
                cur=top->right;	//关键语句,通过让cur等于栈顶元素的右子树.
        }
        return v1;
    }
};

二、非递归实现"中序遍历"

题目链接:传送门

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

补充知识:
二叉树的中序遍历指的是按照从小到大的顺序,依次访问二叉树中的所有节点。即先访问左子树,再访问根节点,最后访问右子树。

中序遍历算法如下:

  1. 如果当前节点的左子树非空,则递归遍历左子树。
  2. 访问当前节点。
  3. 如果当前节点的右子树非空,则递归遍历右子树。

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode

思路分析:

有了前面的前序遍历的思想,对于中序遍历,需要注意的是存入容器(这里是vector)的时机.

  1. 左路节点依次入栈.(与前序对比:此时入栈并没有入容器.)
  2. 栈顶元素入容器,栈顶元素出栈,栈顶元素的右子树子问题解决.

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode
(图片为博主:"初阶牛"原创,未经允许,不得复制)

🔑非递归代码实现:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> s1;
        vector<int> v1;
        TreeNode*  cur=root;
        while(cur||!s1.empty()){
            //沿着左子树一直入节点
            while(cur){
                s1.push(cur);
                cur=cur->left;
            }

            TreeNode* top = s1.top();
            if(top==nullptr)break;
            v1.push_back(top->val);

            //栈顶元素出栈
            s1.pop();
            //右子树 以子问题的方式解决
            if(top->right)
            	cur=top->right;
        }
        return v1;
    }
};

三、非递归实现"后序遍历"

题目链接:传送门

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

二叉树的后序遍历指的是先访问左右子树,最后访问根节点的顺序遍历。即先遍历左子树,再遍历右子树,最后访问根节点。

后序遍历算法如下:

  1. 如果当前节点的左子树非空,则递归遍历左子树。
  2. 如果当前节点的右子树非空,则递归遍历右子树。
  3. 访问当前节点。

思路分析

对于后序遍历,同样注意存入容器的时机,应当是左子树和右子树都访问完毕,才能够访问根节点.

二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode
注意点:
(1)访问结点之前,需要先判断右子树是否已经被访问.

如何判断根节点的右子树已经有没有访问?
答案: 上一个存入的结点是自己右子树,则右子树已经被访问.
上一个结点不是自己的右子树,则右子树未被访问.

示例:
二叉树的前 中 后序的非递归实现(图文详解),C++,算法,数据结构,leetcode文章来源地址https://www.toymoban.com/news/detail-719534.html

💗非递归代码实现:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> s1;
        vector<int> v1;
        TreeNode* prv = nullptr;
        TreeNode* cur = root;
        while (cur || !s1.empty()) {
            //沿着左子树一直入节点
            while (cur) {
                s1.push(cur);
                cur = cur->left;
            }

            TreeNode* top = s1.top();
            if (top == nullptr)break;
            //右子树 以子问题的方式解决
            if (prv!=top->right && top->right) {
                cur = top->right;
                continue;
            }     
            prv=top;
            v1.push_back(top->val);
            //栈顶元素出栈
            s1.pop();
        }
        return v1;
    }
};

到了这里,关于二叉树的前 中 后序的非递归实现(图文详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法练习第13天|递归实现 144.二叉树的前序遍历(opens new window)145.二叉树的后序遍历(opens new window)94.二叉树的中序遍历

    二叉树的存储方式:链式存储和顺序存储。链式存储用指针,顺序存储用数组。其结构如下图所示。 链式存储: 顺序存储: 顺序存储时,若父节点下表为i,则其左孩子下标为 2*i + 1,右孩子下标为2*i + 2. 二叉树主要有两种遍历方式: 深度优先遍历:先往深走,遇到叶子节点

    2024年02月22日
    浏览(51)
  • 【Java数据结构】二叉树的前中后序遍历(递归和非递归)

    二叉树遍历是二叉树的一种重要操作 必须要掌握 二叉树的遍历可以用递归和非递归两种做法来实现 前序遍历的遍历方式是 先根节点 在左节点 在右节点 述这棵树前序遍历的结果是: A B D E C F G 递归的思想就是把问题拆分成一个个小问题来解决 treeNode是一个内部类 具体实现

    2023年04月26日
    浏览(52)
  • 算法刷题Day14 二叉树的前序、中序、后序遍历(递归、迭代、统一迭代方法)

    二叉树的定义 递归 迭代 普通的遍历(包括前序,中序和后续)迭代方法都需要借助到栈 统一迭代 统一迭代使用标记法,在栈中要处理的结点压入空指针 递归 迭代 中序遍历的迭代方法稍微特殊一点 中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问

    2024年02月15日
    浏览(48)
  • LeetCode:二叉树的前、中、后序遍历——如何创建一棵【二叉树】

    🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀 算法专栏: 👉🏻123 二叉树是一种树形数据结构,其每个节点 最多只有两个子节点 。通常将节点分为三种类型:根节点、内部节点和叶子节点。其中,根节点是二叉树的唯一访问起点,内部节点具有一个父

    2023年04月09日
    浏览(45)
  • 力扣(144. 二叉树的前序遍历&&94.二叉树的中序遍历&&145. 二叉树的后序遍历)

    题目链接 题目1: 思路:较简单的思路,就是先将左孩子全部入栈,然后出栈访问右孩子,右孩子为空,再出栈,不为空,右孩子入栈,然后再次循环访问左孩子。 题目链接 题目2: 思路:同前序遍历一样,只不过访问结点,改为出栈时访问。 题目3链接 题目3: 思路1:同样

    2024年01月19日
    浏览(52)
  • 二叉树先序,中序,后序遍历的非递归算法(一)

    思路: 二叉树的前序遍历过程: 从树根开始沿着左子树一直深入,直到最左端无法深入时,返回; 进入最近深入时遇到结点的右子树,再进行如此的深入和返回; 直到最后从根节点的右子树返回到根节点为止; 由其深入返回的过程我们知道可以用一个栈来帮助我们消除递

    2023年04月14日
    浏览(79)
  • 二叉树的前序/中序/后序遍历新手入门介绍

    前序遍历简介也叫先序遍历 前序遍历 可以分为三部分: 根、左子树、右子树 先遍历根节点 、再遍历左子树、再遍历右子树 左/右 子树遍历方法:先访问根节点,再访问 左孩子节点,访问到左孩子节点之后判断该左孩子节点 是否是 叶子节点 (叶子节点 也就是说 这个节点下

    2024年01月17日
    浏览(49)
  • 算法D14 | 二叉树1 | 144. 二叉树的前序遍历 145. 二叉树的后序遍历 94. 二叉树的中序遍历

    理论基础  需要了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义  文章讲解: 二叉树既可以链式存储(利用指针,类似栈和队列),也可以用数组表示。 深度优先遍历 前序遍历(递归法,迭代法) 中序遍历(递归法,迭代法) 后序遍历(递归法,迭代法)

    2024年02月20日
    浏览(38)
  • 用java实现二叉树的后序遍历(递归和迭代)

    目录 1.题目内容 2.用递归实现后序遍历 2.1解题思路 2.2代码 3.用迭代实现后序遍历 3.1解题思路 3.2代码 给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。 示例 1: 输入:root = [1,null,2,3] 输出:[3,2,1] 示例 2: 输入:root = [] 输出:[] 示例 3: 输入:root = [1] 输出:[1]

    2024年02月08日
    浏览(58)
  • 二叉树的非递归遍历算法

    二叉树的遍历是指访问二叉树的每个结点,且每个结点仅被访问一次。二叉树的遍历可按二叉树的构成以及访问结点的顺序分为4种方式:先序遍历、中序遍历、后序遍历和层次遍历。请至少给出其中一种遍历方式的非递归算法的思路和代码,并举例演示算法的执行过程。 算

    2023年04月24日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包