栈和递归的关系 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();
 */

 

posted @ 2019-01-16 23:02  爱学英语的程序媛  阅读(230)  评论(0编辑  收藏  举报