算法训练day14 二叉树递归遍历、迭代遍历、统一遍历

算法训练day14 二叉树递归遍历、迭代遍历、统一遍历

递归遍历

144. 二叉树的前序遍历 - 力扣(LeetCode)

94. 二叉树的中序遍历 - 力扣(LeetCode)

145. 二叉树的后序遍历 - 力扣(LeetCode)

代码随想录 (programmercarl.com)

  • 先序遍历

  • class Solution
    {
    public:
        void traversal(TreeNode *cur, vector<int> &result)
        {
            if (cur == nullptr)
                return;
            result.push_back(cur->val);
            traversal(cur->left, result);
            traversal(cur->right, result);
        }
        vector<int> preorderTraversal(TreeNode *root)
        {
            vector<int> result;
            traversal(root, result);
            return result;
        }
    };
    
  • 中序遍历

  • class Solution
    {
    public:
        void traversal(TreeNode *cur, vector<int> &result)
        {
            if (cur == nullptr)
                return;
    
            traversal(cur->left, result);
            result.push_back(cur->val);
            traversal(cur->right, result);
        }
        vector<int> inorderTraversal(TreeNode *root)
        {
            vector<int> result;
            traversal(root, result);
            return result;
        }
    };
    
  • 后序遍历

  • class Solution
    {
    public:
        void traversal(TreeNode *cur, vector<int> &vec)
        {
            if (cur == NULL)
                return;
            traversal(cur->left, vec);
            traversal(cur->right, vec);
            vec.push_back(cur->val);
        }
        vector<int> postorderTraversal(TreeNode *root)
        {
            vector<int> result;
            traversal(root, result);
            return result;
        }
    };
    

迭代遍历

代码随想录 (programmercarl.com)

  • 前序遍历

  • class Sloulion
    {
        vector<int> preorderTraversal(TreeNode *root)
        {
            stack<TreeNode *> st;
            vector<int> result;
            if (root == NULL)
                return result;
            st.push(root);
            while (!st.empty())
            {
                TreeNode *node = st.top();
                st.pop();
                result.push_back(node->val);
                if (node->right)
                    st.push(node->right);
                if (node->left)
                    st.push(node->left);
            }
            return result;
        }
    };
    
    • 注意入栈时的顺序
  • 中序遍历

  • class Solution
    {
    public:
        vector<int> inorderTraversal(TreeNode *root)
        {
            vector<int> result;
            stack<TreeNode *> st;
            TreeNode *cur = root;
            while (cur != NULL || !st.empty())
            {
                if (cur != NULL)
                {
                    st.push(cur);
                    cur = cur->left;
                }
                else
                {
                    cur=st.top();
                    st.pop();
                    result.push_back(cur->val);
                    cur=cur->right;
                }
            }
            return result;
        }
    };
    
    • 深入到底(指针是否为空),输出值,再检查右节点。
  • 后序遍历

  • class Solution
    {
    public:
        vector<int> postorderTraversal(TreeNode *root)
        {
    
            stack<TreeNode *> st;
            vector<int> result;
            if (root == NULL)
                return result;
            st.push(root);
            while (!st.empty())
            {
                TreeNode *node = st.top();
                st.pop();
                result.push_back(node->val);
                if (node->left)
                    st.push(node->left);
                if (node->right)
                    st.push(node->right);
            }
            reverse(result.begin(), result.end());
            return result;
        }
    };
    
  • 先序是中左右,后续是左右中,实现中右左并翻转以实现后序遍历。

统一遍历

迭代法

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();
            if (node != NULL) {
                st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
                if (node->right) st.push(node->right);  // 添加右节点(空节点不入栈)

                st.push(node);                          // 添加中节点
                st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。

                if (node->left) st.push(node->left);    // 添加左节点(空节点不入栈)
            } else { // 只有遇到空节点的时候,才将下一个节点放进结果集
                st.pop();           // 将空节点弹出
                node = st.top();    // 重新取出栈中元素
                st.pop();
                result.push_back(node->val); // 加入到结果集
            }
        }
        return result;
    }
};

中序:右中左;前序:右左中;后序:中右左

posted @ 2023-09-20 00:14  烫烫烫汤圆  阅读(11)  评论(0)    收藏  举报