首页 > 编程语言 >算法随想Day12【二叉树】| LC144、LC145、LC94-二叉树的前中后序遍历

算法随想Day12【二叉树】| LC144、LC145、LC94-二叉树的前中后序遍历

时间:2023-02-14 23:25:06浏览次数:53  
标签:遍历 curr TreeNode stk vct 二叉树 Day12 LC94 root

LC144、LC145、LC94-二叉树的前中后遍历

二叉树递归遍历

比较容易实现

二叉树非递归遍历

迭代法需要通过使用“栈”来模拟递归的过程

前序遍历:

放入root节点,弹出每个节点时,依次push入该节点的右孩子和左孩子

后序遍历:

由中左右->中右左,翻转结果中右左->左右中,即为后续遍历

中序遍历:

vector记录访问过的节点。先一路向左走,有左孩子的话,就一直push入,直到没左孩子了,pop出,并回到中节点

struct TreeNode
{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x = 0) : val(x), left(nullptr), right(nullptr) {  }
};

class Tree
{
    private:
        TreeNode* _root;

    public:

        /*********递归遍历**********/
        void pre_traversal(TreeNode* curr, vector<int>& vct)
        {
            if(curr == nullptr)
            {
                return;
            }
            // 前序遍历--中左右
            vct.emplace_back(curr->val);
            pre_traversal(curr->left, vct);
            pre_traversal(curr->right, vct);   
        }

        void in_traversal(TreeNode* curr, vector<int>& vct)
        {
            if(curr == nullptr)
            {
                return;
            }
            // 中序遍历--左中右
            in_traversal(curr->left, vct);
            vct.emplace_back(curr->val);
            in_traversal(curr->right, vct);   
        }

        void post_traversal(TreeNode* curr, vector<int>& vct)
        {
            if(curr == nullptr)
            {
                return;
            }
            // 后序遍历--左右中
            post_traversal(curr->left, vct);
            vct.emplace_back(curr->val);
            post_traversal(curr->right, vct);   
        }

        vector<int> preorderTraversal(TreeNode* root)
        {
            vector<int> vct;
            pre_traversal(root, vct);
            return vct;
        }

        vector<int> inorderTraversal(TreeNode* root)
        {
            vector<int> vct;
            in_traversal(root, vct);
            return vct;
        }

        vector<int> postorderTraversal(TreeNode* root)
        {
            vector<int> vct;
            post_traversal(root, vct);
            return vct;
        }


        /*********迭代遍历**********/

        // 前序遍历--中左右(自写成功运行lc144)
        vector<int> preorderTraversal_iteration(TreeNode* root)
        {
            vector<int> vct;
            stack<TreeNode*> stk;
            
            if(root == nullptr) 
                return vct;

            stk.push(root);

            while(!stk.empty())
            {   
                TreeNode* curr = stk.top();
                vct.emplace_back(curr->val);
                stk.pop();

                if(curr->right) stk.push(curr->right);
                if(curr->left) stk.push(curr->left);
            }

            return vct;
        }

        // 后序遍历--左右中,即前序中的中左右,现改为中右左,在将vct整体镜像翻转所得
        vector<int> postorderTraversal_iteration(TreeNode* root)
        {
            vector<int> vct;
            stack<TreeNode*> stk;
            
            if(root == nullptr)
            {
                return vct;
            }

            stk.push(root);

            while(!stk.empty())
            {   
                TreeNode* curr = stk.top();
                vct.emplace_back(curr->val);
                stk.pop();
                
                if(curr->left) stk.push(curr->left);
                if(curr->right) stk.push(curr->right);
            }

            reverse(vct.begin(), vct.end());
            return vct;
        }

        // 中序遍历--左中右
        vector<int> inorderTraversal_iteration(TreeNode* root)
        {
            vector<int> vct;
            stack<TreeNode*> stk;       // 栈中元素代表遍历过的,栈顶表示当前访问的节点
            
            if(root == nullptr) 
                return vct;

            TreeNode* curr = root;      // curr可认为是当前的根节点

            while(curr != nullptr || !stk.empty())
            {   
                if(curr != nullptr)     // 有左子节点,压入,并将左子节点当作新的当前根节点
                {
                    stk.push(curr);
                    curr = curr->left;
                }
                else                    // 发现没左子节点了,退一步改将当前根节点改回上一步,并pop出,并将其右子节点当作新的当前根节点
                {
                    curr = stk.top();
                    stk.pop();
                    vct.emplace_back(curr->val);
                    curr = curr->right;
                }
            }

            return vct;
        }
};

标签:遍历,curr,TreeNode,stk,vct,二叉树,Day12,LC94,root
From: https://www.cnblogs.com/Mingzijiang/p/17121208.html

相关文章

  • 算法刷题-二叉树的锯齿形层序遍历、用栈实现队列_栈设计、买卖股票的最佳时机 IV
    二叉树的锯齿形层序遍历(树、广度优先搜索)给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。例如:给定二......
  • 基于二叉树的高效IP检索格式MMDB
     一、MMDB简介MMDB(MaxMindDatabase)是MaxMind推出的一个数据存储和检索的数据库格式,用于旗下针对IP检索和存储的Geo产品。IP格式由二进制比特数组组成,很容易想到每......
  • L2-011 玩转二叉树 (25 分)
    L2-011 玩转二叉树 (25分)给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换......
  • 剑指 Offer 32 - III. 从上到下打印二叉树 III(java解题)
    目录1.题目2.解题思路3.数据类型功能函数总结4.java代码从上到下打印二叉树系列题目1.剑指Offer32-I.从上到下打印二叉树(java解题)2.剑指Offer32-II.从上......
  • 判断二叉树是否为平衡二叉树
    问题:判断二叉树是否为平衡二叉树面试题55-II.平衡二叉树(从底至顶、从顶至底,清晰图解)-平衡二叉树-力扣(LeetCode)方法一:后序遍历+剪枝,自下而上后续遍历节点,递归向上......
  • 代码随想录算法训练营Day12 栈与队列
    代码随想录算法训练营代码随想录算法训练营Day12栈与队列|239.滑动窗口最大值 347.前K个高频元素 总结239.滑动窗口最大值给定一个数组nums,有一个大小为 k......
  • 代码随想录算法训练营Day12 栈与队列
    代码随想录算法训练营代码随想录算法训练营Day12栈与队列|239.滑动窗口最大值 347.前K个高频元素 总结239.滑动窗口最大值给定一个数组nums,有一个大小为 k......
  • leetcode144-二叉树的前序遍历
    leetcode144-二叉树的前序遍历​​1、问题描述​​​​2、递归解法​​1、问题描述  给你二叉树的根节点​​root​​,返回它节点值的前序遍历。  示例1:输入:root=[......
  • 二叉树
    一、二叉树的定义二叉树是n(n≥0)个结点组成的有限集合。当n=0时,称为空二叉树;当n>0时,该集合由一个根节点及两颗互不相交的,被分别成为左子树和右子树的二叉树组成。二......
  • 输出二叉树第h层上的所有结点(1<=h<=k)
    输出二叉树第h层上的所有结点(1<=h<=k)问题引入:已知一颗二叉链表方式存储的深度为k的二叉树,根结点是第1层。编写算法,输出第h层所有结点,1<=h<=k。分析二叉树的算......