zoukankan      html  css  js  c++  java
  • 栈和递归的关系 144:Binary Tree Preorder Traversal

    前序遍历:根左右

    //用栈来实现非递归解法
    /*
    * * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> preorderTraversal(TreeNode* root) { vector<int> res; if(root == NULL) return res; stack<TreeNode*> stack; stack.push(root); while(!stack.empty()){ TreeNode* c = stack.top(); stack.pop(); res.push_back(c->val); if(c->right) stack.push(c->right); if(c->left) stack.push(c->left); } return res; } };
    //递归解法,注意res是全局的,要放在遍历函数外面
    /*
    * * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> res; vector<int> preorderTraversal(TreeNode* root) { if(root){ res.push_back(root->val); preorderTraversal(root->left); preorderTraversal(root->right); } return res; } };

    中序遍历:左根右

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        
        vector<int> inorderTraversal(TreeNode* root) {
            stack<TreeNode*> st;
            vector<int> res;
            if(root == NULL) return res;  //若根节点为空则返回空
            TreeNode* p = root;
            while(p || !st.empty()){
                while(p){
                    //先将根节点入栈,再将它所有的左节点入栈
                    st.push(p);
                    p = p->left;   
                }
                
                p = st.top();
                st.pop();
                res.push_back(p->val);
                p = p->right;
            }
            return res;
        }
    };

     后序遍历:左右根

    可以使其遍历顺序为根左右,然后逆序插入vector中,即每次在vector的头部插入结点值。在压入栈时先压入右结点再压入左结点则在出栈时就是先左后右了。

    //解法一
    /*
    * * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> postorderTraversal(TreeNode* root) { if(!root) return {}; vector<int> res; stack<TreeNode*> s{{root}}; while(!s.empty()){ TreeNode* t = s.top(); s.pop(); res.insert(res.begin(), t->val); if(t->left) s.push(t->left); if(t->right) s.push(t->right); } return res; } };

    解法二:关键是判断当前这个结点:

    1)它如果有左右结点是否已经入栈,若没有入栈则先将它的右结点入栈,再左结点入栈;如果它的左右结点已经入栈,则这个结点就可以直接加入容器vector里了。

    2)如果它是叶子结点(没有左右结点),则直接加入vector中。

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<int> postorderTraversal(TreeNode* root) {
            if(!root) return {};
            vector<int> res;
            stack<TreeNode*> s{{root}};
            TreeNode* head = root;   //head初始化
            while(!s.empty()){
                TreeNode* t = s.top();
                if((!t->left && !t->right) || t->left==head || t->right==head){
                    //当t为叶子结点 或t的左结点或右结点为head,即已经入栈了
                    res.push_back(t->val);
                    s.pop();
                    head = t;
                }
                else{
                    if(t->right) s.push(t->right);
                    if(t->left) s.push(t->left);
                }
            }
            return res;
        }
    };

    leetcode已经分别定义了类NestedInteger中的三个函数:

    1)isInteger():若当前这个NestedInteger是单个整数返回true;

    2)getInteger():返回当前这个单个的整数;

    3)getList():返回当前这个列表。

    /**
     * // This is the interface that allows for creating nested lists.
     * // You should not implement it, or speculate about its implementation
     * class NestedInteger {
     *   public:
     *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
     *     bool isInteger() const;
     *
     *     // Return the single integer that this NestedInteger holds, if it holds a single integer
     *     // The result is undefined if this NestedInteger holds a nested list
     *     int getInteger() const;
     *
     *     // Return the nested list that this NestedInteger holds, if it holds a nested list
     *     // The result is undefined if this NestedInteger holds a single integer
     *     const vector<NestedInteger> &getList() const;
     * };
     */
    class NestedIterator {
    public:
        stack<NestedInteger> s;
        
        NestedIterator(vector<NestedInteger> &nestedList) {
            for(int i=nestedList.size()-1; i>=0; i--)
                //倒序插入 是为了弹出时是正序的
                s.push(nestedList[i]);
        }
    
        int next() {
            //返回下一项的值
            NestedInteger t = s.top();
            s.pop();
            return t.getInteger();  //获取对应整数
            
        }
    
        bool hasNext() {
            //若下一项有值,返回true
            while(!s.empty()){
                NestedInteger t = s.top();
                if(t.isInteger())
                    return true;   //若下一个数是单个整数,返回true
                s.pop();
                //若下一个数是一个列表,使用getList()得到列表的每个整数倒序插入到栈中
                for(int i=t.getList().size()-1; i>=0; i--)
                    s.push(t.getList()[i]);
            }
            return false;
        }
    };
    
    /**
     * Your NestedIterator object will be instantiated and called as such:
     * NestedIterator i(nestedList);
     * while (i.hasNext()) cout << i.next();
     */
  • 相关阅读:
    仿联想商城laravel实战---6、自建配置文件和缓存(如何读取自己创建的配置文件的信息)
    php中相对路径和绝对路径如何使用(详解)
    英语影视台词---绿皮书(2)(利普 我以为你要把那家伙打死了)
    仿联想商城laravel实战---5、无刷新的增删改查(动态页面更新的三种方式(html))
    英语发音规则---ea字母组合发音规律
    英语发音规则---ir字母组合发音规律
    仿联想商城laravel实战---4、验证(lavarel的表单验证如何使用)
    android adb 不同的方式使用特定的解释
    Spring aop 小例子demo
    SPOJ 15. The Shortest Path 堆优化Dijsktra
  • 原文地址:https://www.cnblogs.com/Bella2017/p/10279952.html
Copyright © 2011-2022 走看看