代码随想录算法训练营第十四天 | 二叉树遍历

递归法

文章讲解 视频讲解
递归三要素:
1 确定递归函数的参数和返回值
2 确定终止条件
3 确定单层递归的逻辑

前序遍历

题目链接

  1. 递归的参数和返回值:传入当前节点和保存结果集的数组,不需要返回值
  2. 终止条件:当前节点为空时
  3. 单层递归逻辑:保存当前节点的值到结果集中
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        traversal(root, ans);
        return ans;
    }
    void traversal(TreeNode* node, vector<int>& ans) {
        if(node == nullptr) return ;
        ans.push_back(node->val);  // 根
        traversal(node->left, ans);  // 左
        traversal(node->right, ans);  // 右
    }
};

中序遍历

题目链接

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        traversal(root, ans);
        return ans;
    }
    void traversal(TreeNode* node, vector<int>& ans){
        if(node == nullptr) return ;
        traversal(node->left, ans);  // 左
        ans.push_back(node->val);  // 根
        traversal(node->right, ans);  // 右
    }
};

后序遍历

题目链接

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        traversal(root, ans);
        return ans;
    }
    void traversal(TreeNode* node, vector<int>& ans) {
        if(node == nullptr) return ;
        traversal(node->left, ans);  // 左
        traversal(node->right, ans);  // 右
        ans.push_back(node->val);  // 根
    }
};

迭代法

文章讲解

思路:递归遍历就是将当前结果保存在栈中,等到返回的时候再从栈顶弹出保存的结果,所以可以用栈来模拟递归的方式来实现堆二叉树的遍历

前序遍历

视频讲解

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> st;
        if(root == nullptr) return {};
        st.push(root);
        while(!st.empty()) {
            TreeNode* node = st.top();
            st.pop();
            // 需调整入栈顺序来保证出栈顺序为根左右
            if(node == nullptr) continue;
            ans.push_back(node->val);  // 根
            st.push(node->right);  // 右
            st.push(node->left);  // 左
        }
        return ans;
    }
};

中序遍历

视频讲解

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> st;
        TreeNode * cur = root;
        while(cur || !st.empty()) {
            if(cur) {
                st.push(cur);
                cur = cur->left;
            } else {
                cur = st.top();
                ans.push_back(cur->val);
                st.pop();
                cur = cur->right;
            }
        }
        return ans;
    }
};

后序遍历

视频讲解

思路:直接用栈来调整是很难满足后续遍历要求的会陷入复杂的逻辑判断中;
这是可以观察前序遍历是根->左->右, 而后序遍历是左->右->根,秩序调前序遍历代码的入栈顺序为先左后右,就可以得到:
根->右->左的顺序,最后将数组反转就可以得到正确的顺序

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> st;
        if(root == nullptr) return {};
        st.push(root);
        
        while(!st.empty()) {
            TreeNode* node = st.top();
            ans.push_back(node->val);
            st.pop();
            if(node->left) st.push(node->left);
            if(node->right) st.push(node->right);
        }
        reverse(ans.begin(), ans.end());


        return ans;
    }
};
posted @ 2024-05-22 12:21  深蓝von  阅读(3)  评论(0编辑  收藏  举报