跳转至

94/144/145. 二叉树的前/中/后序遍历

力扣链接(简单):https://leetcode.cn/problems/binary-tree-inorder-traversal

力扣链接(简单):https://leetcode.cn/problems/binary-tree-preorder-traversal

力扣链接(简单):https://leetcode.cn/problems/binary-tree-postorder-traversal

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

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

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

提示:

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

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

个人题解

前序遍历

递归法

C++
/**
 * 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 traversal(TreeNode* current, vector<int>& vec) {
        if(!current) return;
        vec.push_back(current->val);    // mid
        traversal(current->left, vec);  // left
        traversal(current->right, vec); // right
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root, res);
        return res;
    }
};

迭代法

C++
/**
 * 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;
        // 二叉树DFS很适合用栈来解决
        stack<TreeNode*> st;

        if(!root) return res;

        // 压入根节点
        st.push(root);
        while(!st.empty()) {
            // 先弹出各子树的根节点(中间节点)
            auto node = st.top();
            res.push_back(node->val);
            st.pop();
            // 这里之所以先压右子树,那是因为弹出顺序是和压入顺序相反的
            // 这样才能得到中左右的遍历顺序
            // 压入右子树根节点
            if(node->right) st.push(node->right);
            // 压入左子树根节点
            if(node->left) st.push(node->left);
        }
        return res;
    }
};

中序遍历*

递归法

C++
/**
 * 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 traversal(TreeNode* current, vector<int>& vec) {
        if(!current) return;
        traversal(current->left, vec);  // left
        vec.push_back(current->val);    // mid
        traversal(current->right, vec); // right
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root, res);
        return res;
    }
};

迭代法*

C++
/**
 * 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*> st;
        while(root || !st.empty()) {
            // 中序遍历是先要找到最左边的节点,然后再依次向上输出
            // 从root一直向左遍历下去
            if(root) {
                // 压入当前节点
                st.push(root);
                root = root->left;
            } else {
                // 当前遍历到的root为NULL了,代表st.top()是叶子节点
                root = st.top();
                st.pop();
                // 将当前节点存入结果
                res.push_back(root->val);
                // 然后继续遍历当前节点的右子树
                root = root->right;
            }
        }
        return res;
    }
};

后序遍历

递归法

C++
/**
 * 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 traversal(TreeNode* current, vector<int>& vec) {
        if(!current) return;
        traversal(current->left, vec);  // left
        traversal(current->right, vec); // right
        vec.push_back(current->val);    // mid
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root, res);
        return res;
    }
};

迭代法

C++
/**
 * 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) {
        vector<int> res;
        // 二叉树DFS很适合用栈来解决
        stack<TreeNode*> st;

        if(!root) return res;

        // 压入根节点
        st.push(root);
        while(!st.empty()) {
            // 先弹出各子树的根节点(中间节点)
            auto node = st.top();
            res.push_back(node->val);
            st.pop();
            // 这里之所以先压左子树,那是因为弹出顺序是和压入顺序相反的
            // 这样才能得到中右左的遍历顺序,最后再反转,就是左右中了
            // 压入左子树根节点
            if(node->left) st.push(node->left);
            // 压入右子树根节点
            if(node->right) st.push(node->right);
        }
        // 中右左 -> 左右中
        reverse(res.begin(), res.end());
        return res;
    }
};