代码随想录第五十八期day13

代码随想录第五十八期day13

题目一:144. 二叉树的前序遍历
题目描述:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

输入:root = [1,null,2,3]

输出:[1,2,3]

解释:

示例 2:

输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出:[1,2,4,5,6,7,3,8,9]

解释:

示例 3:

输入:root = []

输出:[]

示例 4:

输入:root = [1]

输出:[1]

提示:

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

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

解析:本题递归算法很简单,所以用一个递归就能完成,写递归时要注意终止条件,不能写成没用终止条件的递归,本题终止条件就是当节点为空时候,就结束递归。具体代码如下:

/**
 * 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 digui(TreeNode* cur,vector<int> &vec){
        if(cur == NULL)return;
        vec.push_back(cur->val);
        digui(cur->left,vec);
        digui(cur->right,vec);

    }
    vector<int> preorderTraversal(TreeNode* root) {
        //递归前序遍历二叉树
        vector<int>a;
        digui(root,a);
        return a;
        
        
    }
};

解法二:迭代法前序遍历二叉树,首先递归也是使用栈来实现的递归,基于此,我们也可以使用栈来对二叉树进行前序遍历,由于栈是后进先出,所以我们要先压入右子树,再压入左子树,这样才能保证先访问左字数,具体代码如下:

/**
 * 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> preorderTraversal(TreeNode* root) {
        stack<TreeNode*>a;
        vector<int>result;
        if(root == NULL)return result;
        a.push(root);
        TreeNode* p=root;
        //TreeNode* q=root;
        while(!a.empty()){
            p=a.top();
            a.pop();
            result.push_back(p->val);
            if(p->right !=NULL)a.push(p->right);
            if(p->left != NULL)a.push(p->left);
        }
            return result;
    }
};

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

示例 1:

输入:root = [1,null,2,3]

输出:[3,2,1]

解释:

示例 2:

输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出:[4,6,7,5,2,9,8,3,1]

解释:

示例 3:

输入:root = []

输出:[]

示例 4:

输入:root = [1]

输出:[1]

提示:

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

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

解析:其实二叉树的前中后递归遍历很简单,就是交换代码位置即可,本题的后续遍历,那就把访问节点在递归函数里面写在找节点的后面即可,后面还有一道是中序遍历的,就把访问节点放在中间即可,具体后序遍历代码如下:

/**
 * 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) {}
 * };
 */

/**
 * 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 digui(TreeNode* cur,vector<int> &vec){
        if(cur == NULL)return;
        digui(cur->left,vec);
        digui(cur->right,vec);
        vec.push_back(cur->val);

    }
    vector<int> postorderTraversal(TreeNode* root) {
        //递归前序遍历二叉树
        vector<int>a;
        digui(root,a);
        return a;   
    }
};


解法二:迭代法后序遍历二叉树;由上一题我们知道了迭代遍历二叉树,现在我们也是在里面修改一下位置即可。本题也是初次看见,具体可以看Carl哥讲解不用去具体实现什么,在前序上直接改一下就行,只能说太强了,具体代码如下:

/**
 * 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*>a;
        vector<int>result;
        if(root == NULL)return result;
        a.push(root);
        TreeNode* p=root;
        while(!a.empty()){
            p=a.top();
            a.pop();
            result.push_back(p->val);
            if(p->left != NULL)a.push(p->left);
            if(p->right !=NULL)a.push(p->right);
        }
        reverse(result.begin(),result.end());
            return result;
    }
};

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

示例 1:

输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:

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

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

提示:

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

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

解析:递归算法很简单,具体只要在前序和后序里面的代码改一下位置即可,具体代码如下:

/**
 * 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 digui(TreeNode* cur,vector<int> &vec){
        if(cur == NULL)return;
        digui(cur->left,vec);
        vec.push_back(cur->val);
        digui(cur->right,vec);
    }
    vector<int> inorderTraversal(TreeNode* root) {
         vector<int>a;
        digui(root,a);
        return a;   
    }
};

下面我们介绍迭代算法,本题的迭代算法和前序和后序不一样,对于中序遍历来说,先访问左子树在访问根节点最后访问右节点,所以循环里面我们要先找到最左端点节点,才能继续下一步操作,具体代码如下,由于写错了,然后问豆包,所以它给出了正确的写法:

/**
 * 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*> stk;
        TreeNode* curr = root; //  独立指针,避免污染栈
        
        while (curr || !stk.empty()) { //  循环条件:curr非空 或 栈非空
            // 1. 向左走到尽头,沿途压栈(含当前节点)
            while (curr) {
                stk.push(curr);
                curr = curr->left;
            }
            
            // 2. 取出栈顶(最左节点),处理「根」
            curr = stk.top();
            stk.pop();
            res.push_back(curr->val);
            
            // 3. 转向右子树(无需压栈,外层循环会重新处理)
            curr = curr->right; 
        }
        
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值