力扣 144,94,145 二叉树前中后序遍历 [递归,Morris]

二叉树不同遍历介绍

请查看这里
 

144. 二叉树的前序遍历

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

示例 1:

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

递归

使用递归,每次都首先记录val,再按先左后右的顺序进入递归。

查看代码
 /**
 * 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 work(TreeNode* root,vector<int>& t){
        if(!root)
            return;
        t.push_back(root->val);
        if(root->left)
            work(root->left,t);
        if(root->right)
            work(root->right,t);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> t;
        work(root,t);
        return t;
    }
};

迭代

递归的流程就是深度遍历,先放进去的节点反而会最后访问,和栈的思想一样,

递归实质是使用系统栈,那我们可以直接使用栈来模拟递归的流程,

注意递归时先左后右,可是使用栈,因为先进后出,所以需要先右后左。

查看代码
 /**
 * 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) {
        vector<int> t;
        stack<TreeNode*> st;
        if(!root)
            return t;
        st.push(root);
        while(!st.empty()){
            TreeNode* cur=st.top();
            st.pop();
            t.push_back(cur->val);
            if(cur->right)
                st.push(cur->right);
            if(cur->left)
                st.push(cur->left);
        }
        return t;
    }
};

Morris遍历

Morris遍历的介绍在这里

查看代码
/**
 * 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) {
        vector<int> res;
        TreeNode *curr = root;
        while (curr != NULL)
        {
            if (curr->left == NULL)
            {
                res.emplace_back(curr->val);//输出当前节点
                curr = curr->right;
            }
            else
            {
                // 找当前节点的前趋结点
                TreeNode* predecessor = curr->left;
                while (predecessor->right != NULL&& predecessor->right != curr)
                {
                    predecessor = predecessor->right;
                }

                // 使当前节点成为inorder的前序节点的右侧子节点
                if (predecessor->right == NULL)
                {
                    predecessor->right = curr;
                    res.emplace_back(curr->val);//输出当前节点
                    curr = curr->left;
                }

                //复原之前的修改
                else
                {
                    predecessor->right = NULL;
                    curr = curr->right;
                }
            }
        }
        return  res;
    }
};

94. 二叉树的中序遍历

给定一个二叉树的根节点 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 work(TreeNode* root,vector<int> &t){
        if(!root)
            return;
        if(root->left)
            work(root->left,t);
        t.push_back(root->val);
        if(root->right)
            work(root->right,t);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> t;
        work(root,t);
        return t;
    }
};

Morris

Morris
 /**
 * 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;
        TreeNode *curr = root;
    
        while (curr != NULL)
        {
            if (curr->left == NULL)
            {
                res.emplace_back(curr->val);//输出当前节点
                curr = curr->right;
            }
            else
            {
                // 找当前节点的前趋结点
                TreeNode* predecessor = curr->left;
                while (predecessor->right != NULL
                    && predecessor->right != curr)
                {
                    predecessor = predecessor->right;
                }

                // 使当前节点成为inorder的前序节点的右侧子节点
                if (predecessor->right == NULL)
                {
                    predecessor->right = curr;
                    curr = curr->left;
                }

                //复原之前的修改
                else
                {
                    predecessor->right = NULL;
                    res.emplace_back(curr->val);//输出当前节点
                    curr = curr->right;
                }
            }
        }
        return res;
    }
};

145. 二叉树的后序遍历

给你一棵二叉树的根节点 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 work(TreeNode* root,vector<int>& t){
        if(!root)
            return;
        if(root->left)
            work(root->left,t);
        if(root->right)
            work(root->right,t);
        t.push_back(root->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> t;
        work(root,t);
        return t;
    }
};

 Morris

后序
 /**
 * 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) {
        TreeNode* node = root;
        vector<int> res;//需要有一个遍历存储路径,当然也可以用vector存储,然后翻转
        while(node) {
            if(!node->right) {//这里就不需要输出了
                res.emplace_back(node->val);//
                node = node->left;
            }
            else {
                TreeNode* prev = node->right;//predecessor

                while(prev->left && prev->left != node)//这里与preorder相反
                    prev = prev->left;

                if(!prev->left) {//同上
                    prev->left = node;
                    res.emplace_back(node->val);//
                    node = node->right;
                }
                else {//同上  
                    node = node->left;
                    prev->left = NULL;
                }
            }
        }

        reverse(res.begin(),res.end());
        return res;
    }
};
posted @ 2022-09-13 15:36  付玬熙  阅读(42)  评论(0编辑  收藏  举报