风也温柔

计算机科学知识库

二叉树遍历算法 java 二叉树遍历系列

  二叉树的遍历

  递归遍历思路解析

  二叉树的前中后序遍历,其实就是递归的简单应用二叉树遍历算法 java二叉树遍历算法 java 二叉树遍历系列,写递归我一般先写递归出口和边界,这样能更容易理清思路。

  学过数据结构的朋友二叉树遍历算法 java,二叉树递归遍历的原理应该不用再介绍了。下面就看代码吧。

  手撕代码

   //前序遍历

    class Solution {
    private:
        vector res;
    public:
        
        vector& preorderTraversal(TreeNode* root) {
            //方法的返回值是成员变量的引用,若使用局部变量,请使用值传递的方式。
            helper(root, res);
            return res;
    ​
        }
        void helper(TreeNode* root, vector& res) {
    ​
            if (root != nullptr) {
                res.push_back(root->val);
                if (root->left != nullptr) {
                    helper(root->left, res);
                }
                if (root->right != nullptr) {
                    helper(root->right, res);
                }
            }
        }
    };
    ​
    //[中序遍历][5]
    class Solution {
    private:
        vector res;
    public:
        vector& inorderTraversal(TreeNode* root) {
            helper(root, res);
            return res;
        }
        void helper(TreeNode* root, vector& res) {
            if (root != nullptr) {
                if (root->left != nullptr) {
                    helper(root->left, res);
                }
                
                res.push_back(root->val);
                if (root->right != nullptr) {
                    helper(root->right, res);
                }
            }
        }
    };
    ​
    //后序遍历
    class Solution {
    private:
        vector res;
    public:
        vector& postorderTraversal(TreeNode* root) {
            helper(root, res);
            return res;
    ​
        }
        void helper(TreeNode* root, vector& res) {
            if (root != nullptr) {
                if (root->left != nullptr) {
                    helper(root->left, res);
                }
                if (root->right != nullptr) {
                    helper(root->right, res);
                }
                res.push_back(root->val);
            }
        }
    };

  迭代遍历

  二叉树的迭代遍历就是不再使用系统栈,用循环代替递归

  前序遍历

   //前序遍历

    //第一种解法
    //改解法在栈中保存了二叉树的左右子树,更符合人工遍历二叉树时的思维
    class Solution {
    private:
        vector res;
    public:
        vector& preorderTraversal(TreeNode* root) {
            stack stack;
            if (root == nullptr)
                return res;
            TreeNode* ptr = root;
            while (ptr || !stack.empty()) {
                if(ptr){
                    res.push_back(ptr->val);
                    stack.push(ptr);
                    ptr = ptr->left;
                }
                else
                {
                    ptr = stack.top();
                    ptr = ptr->right;
                    //这里记得一定要pop,因为前序遍历中,访问了该节点的右子树后,该节点就再也不用被访问了。
                    stack.pop();
                    
                }
            }
            return res;
        }
    };
    //第二种解法
    //该解法是前一种在形式上的简化版,只需要在栈中保存右子树即可。
    class Solution {
    private:
        vector res;
    public:
        vector& preorderTraversal(TreeNode* root) {
            stack stack;
            if (root == nullptr)
                return res;
            TreeNode* ptr = root;
            while (ptr || !stack.empty()) {
                if (ptr) {
                    res.push_back(ptr->val);
                    if (ptr->right) {
                        stack.push(ptr->right);
                    }
                    ptr = ptr->left;
                }
                else
                {
                    ptr = stack.top();
                    stack.pop();
                }
            }
            return res;
        }
    };
    ​
    //这种解法其实也是利用了前序遍历先遍历根,再遍历左子树,最后右子树的特性,结合栈先进后出的特性去实现。
    class Solution {
    private:
        vector res;
    public:
    ​
        vector& preorderTraversal(TreeNode* root) {
            stack stack;
    ​
            if (root == nullptr)
                return res;
            stack.push(root);
            TreeNode* ptr = nullptr;
            while (!stack.empty())
            {
                ptr = stack.top();
                stack.pop();
                res.push_back(ptr->val);
                if (ptr->right)
                    stack.push(ptr->right);
                if (ptr->left)
                    stack.push(ptr->left);
            }
            return res;
        }
    };
    ​
    ​
    ​

  中序遍历

   class Solution {

    public:
        vector inorderTraversal(TreeNode* root) {
            vector res;
            stack st;
            TreeNode* ptr = root;
    ​
            while (ptr || !st.empty()) {
                if (ptr) {
                    st.push(ptr);
                    ptr = ptr->left;
                }
                else {
                    ptr = st.top();
                    st.pop();
                    res.push_back(ptr->val);
                    ptr = ptr->right;
                }
            }
            return res;
        }
    };

  后序遍历

   //这种做法丢失了后序遍历从前到后的顺序

    class Solution {
    public:
        vector postorderTraversal(TreeNode *root) {
            stack nodeStack;
            vector result;
            //base case
            if(root==NULL)
            return result;
            nodeStack.push(root);
            while(!nodeStack.empty())
            {
                TreeNode* node= nodeStack.top();  
                result.push_back(node->val);
                nodeStack.pop();
                if(node->left)
                nodeStack.push(node->left);
                if(node->right)
                nodeStack.push(node->right);
            }
             reverse(result.begin(),result.end());
             return result;
        }  
    };
    ​
    //更欣赏这种写法
    class Solution {
    public:
        vector postorderTraversal(TreeNode* root) {
            vector res;
            if (root == nullptr){
                return res;
            }
            TreeNode* ptr = root;
            TreeNode* last = nullptr;
            stack st;
            while(ptr || !st.empty()){
                if (ptr){
                    st.push(ptr);
                    ptr = ptr->left;
                }
                else{
                    TreeNode* node = st.top();
                    if(node->right && last!= node->right){
                        ptr = node->right;
                    }
                    else{
                        res.push_back(node->val);
                        last = node;
                        st.pop();
                    }
                }
            }
            return res;
        }
    };

  文章来源:https://zhuanlan.zhihu.com/p/157654452