二刷代码随想录算法训练营第十四天 | 二叉树前、中、后序遍历

一、二叉树的前、中、后序遍历基础

题目链接:力扣力扣力扣

文章讲解:代码随想录

视频讲解: 写出二叉树的非递归遍历很难么?(前序和后序)

题目:

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

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

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

代码:

前序遍历
/**
 * 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:
    /*void build(TreeNode *node,vector<int>& ans)//确定递归函数的参数和返回值
    {
        if (node == NULL) return;//确定终止条件
        //确定单层递归的逻辑
        ans.push_back(node->val);//中
        build(node->left, ans);//左
        build(node->right, ans);//右
        return;
    }*/
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        //递归法
        //build(root, ans);
        //迭代法
        stack<TreeNode*> stack;//二叉树深度遍历递归用栈
        if (root == NULL) return {};
        stack.push(root);
        /*while (!stack.empty())
        {
            TreeNode *node = stack.top();
            stack.pop();
            ans.push_back(node->val);//中   处理返回数组

            if (node->right) stack.push(node->right);//右   先放后弹
            if (node->left) stack.push(node->left);//左
        }*/
        //统一迭代法
        while (!stack.empty())
        {
            root = stack.top();// 指向一个结点确定位置
            if (root != NULL)
            {
                stack.pop();//确定位置的指针并不是要被处理的
                if (root->right) stack.push(root->right);//右
                if (root->left) stack.push(root->left);//左
                stack.push(root);//中
                stack.push(NULL); //中的处理标记
            }
            else//返回数组处理标记
            {
                stack.pop();
                root = stack.top();//及时pop以免忘记
                stack.pop();
                ans.push_back(root->val);
            }
        }
        return ans;
    }
};
后序遍历
/**
 * 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:
    /*void build(TreeNode *node, vector<int> &ans)
    {
        if (node == NULL) return;
        build(node->left, ans);
        build(node->right, ans);
        ans.push_back(node->val);
        return;
    }*/
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        //递归法
        //build(root, ans);
        //迭代法
        stack<TreeNode*> stack;
        if (!root) return{};
        stack.push(root);
        /*while (!stack.empty())
        {
            TreeNode *node = stack.top();
            stack.pop();
            ans.push_back(node->val);
            if (node->left) stack.push(node->left);
            if (node->right) stack.push(node->right);
        }
        reverse(ans.begin(), ans.end());*///中右左  反转成   左右中
        //统一迭代法
        while (!stack.empty())
        {
            root = stack.top();
            if (root != NULL)
            {
                stack.pop();
                stack.push(root);
                stack.push(NULL);
                if (root->right) stack.push(root->right);
                if (root->left) stack.push(root->left);
            }
            else
            {
                stack.pop();
                root = stack.top();
                stack.pop();
                ans.push_back(root->val);
            }
        }
        return ans;
    }
};
中序遍历
/**
 * 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:
    /*void build(TreeNode *node, vector<int> &ans)
    {
        if (node == NULL) return;
        build(node->left, ans);
        ans.push_back(node->val);
        build(node->right,ans);
        return;
    }*/
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        //递归法
        //build(root, ans);
        //迭代法
        stack<TreeNode*> stack;
        /*while (root != NULL || !stack.empty())  
        {
            if (root) // 指针确定位置在最底层
            {
                stack.push(root); // 不断将左侧入栈
                root = root->left;
            }
            else//处理返回数组的标志
            {
                root = stack.top();  
                stack.pop();
                ans.push_back(root->val); //左即中 中
                root = root->right; // 右
            }
        }*/
        //统一迭代法
        if (!root) return {};
        stack.push(root);
        while(!stack.empty())
        {
            root = stack.top();
            if (root != NULL)
            {
                stack.pop();
                if (root->right) stack.push(root->right);
                stack.push(root);
                stack.push(NULL);
                if (root->left) stack.push(root->left);
            }
            else
            {
                stack.pop();
                root = stack.top();
                stack.pop();
                ans.push_back(root->val);
            }
        }
        return ans;
    }
};

总结:

1.递归法:(1)确定递归函数的参数和返回值 (2)确定终止条件 (3)确定单层递归的逻辑   

2.迭代法:(1) 注意左右中的顺序略有不同  (2) 中序遍历的写法与前序遍历不同。前序遍历直接处理根结点,然后将左右压入栈中。中序遍历需用指针往左移到底层,再处理左即中结点,接着指针指向右结点。

3.统一迭代法:(1)将入栈与处理返回数组分开 ,先用指针指向一个结点位置,再执行相应入栈操作,如果达到处理返回数组条件(条件:结点为NULL,注意:在栈中的中后放一个NULL标记), 就处理返回数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值