Binary Tree Traversal In Three Ways In Leetcode

144. 二叉树的前序遍历

class Solution {
public:
    vector<int> ans;
    //递归版本
    /*
    void previsit(TreeNode* r)
    {
        if(r != NULL)
        {
            ans.push_back(r->val);
            previsit(r->left);
            previsit(r->right);
        }
    }*/
    // 非递归版本 借助于栈
    /*
    void previsit(TreeNode* r)
    {
        stack<TreeNode*> s;
        s.push(r);
        while(!s.empty())
        {
            r= s.top();
            s.pop();
            
            if(r!=NULL)
            {
                ans.push_back(r->val);
                s.push(r->right);
                s.push(r->left);
            }
        }
    }
    */
    // 非递归版本,模拟编译器的行为
    void previsit(TreeNode *r)
    {
        if(r == NULL)
            return;
        
        stack<pair<TreeNode*, int>> s;
        auto snode = make_pair(r,0);
        
        while( 1 )
        {
            //snode.first == NULL 对应于左节点或者是右节点为空的情况。
            //snode.second >= 3 对应的是这个函数题中的代码顺序执行完了的情况 这样就可以直接回退,也就是出栈了。
            while(!s.empty() && (snode.first == NULL ||  snode.second >= 3))
            {
                snode = s.top();
                s.pop();
                ++snode.second;
            }
            
            //栈为空了 并且还处于这种状态,就说明已经处理完了,退出循环就行了
            if(snode.first == NULL || snode.second >= 3)
            {
                break;
            }
            
            //转台转移 就是所写的递归代码
            switch( snode.second )
            {
                case 0:
                    ans.push_back(snode.first->val);
                    ++snode.second;
                    break;
                case 1:
                    s.push(snode);
                    snode.first = snode.first->left;
                    snode.second = 0;
                    break;
                case 2:
                    s.push(snode);
                    snode.first = snode.first->right;
                    snode.second = 0;
                    break;
                default:
                    break;
            }
        } 
    }
    
    vector<int> preorderTraversal(TreeNode* root) {
        ans.clear();
        previsit(root);
        return ans;
    }
};

94. 二叉树的中序遍历

class Solution {
public:
    vector<int> ans;
    //递归版本
    /*
    void invisit(TreeNode* root)
    {
        if(root)
        {
            invisit(root->left);
            ans.push_back(root->val);
            invisit(root->right);
        }
    }*/
   // 非递归版本1
    /*
    void invisit(TreeNode* r)
    {
        stack<TreeNode*> s;
        while(!s.empty() || r!=NULL)
        {
            while(r!=NULL)
            {
                s.push(r);
                r = r->left;
            }
            if(!s.empty())
            {
                r = s.top();
                s.pop();
                ans.push_back(r->val);
                r = r->right;
            }
        }
    }
    */
    // 非递归版本2
    /*
     TreeNode* goLeftFastest(TreeNode *r, stack<TreeNode*> &s)
     {
         if( r== NULL)
             return NULL;
         
         while(r->left!=NULL)
         {
             s.push(r);
             r = r->left;
         }
         return r;
     }
    void invisit(TreeNode* r)
    {
        if(r==NULL)
            return;
        
        stack<TreeNode*> s;
        r = goLeftFastest(r,s);
        while(r!=NULL)
        {
            ans.push_back(r->val);
            if(r->right!=NULL)
            {
                r = goLeftFastest(r->right,s);
                
            }else if(!s.empty())
            {
                r = s.top();
                s.pop();
            }else
            {
                break;
            }
        }
    }
    */
    //非递归版本,借助于模拟编译器的行为
    void invisit(TreeNode *r)
    {
        if(r == NULL)
            return;
        
        stack<pair<TreeNode*, int>> s;
        auto snode = make_pair(r,0);
        while( 1 )
        {
            //snode.first == NULL 对应于左节点或者是右节点为空的情况。
            //snode.second >= 3 对应的是这个函数题中的代码顺序执行完了的情况 这样就可以直接回退,也就是出栈了。
            while(!s.empty() && (snode.first == NULL ||  snode.second >= 3))
            {
                snode = s.top();
                s.pop();
                ++snode.second;
            }
            //栈为空了 并且还处于这种状态,就说明已经处理完了,退出循环就行了
            if(snode.first == NULL || snode.second >= 3)
            {
                break;
            }
            //转台转移 就是所写的递归代码
            switch( snode.second )
            {
                    /*
                case 0:
                    ans.push_back(snode.first->val);
                    ++snode.second;
                    break;
                case 1:
                    s.push(snode);
                    snode.first = snode.first->left;
                    snode.second = 0;
                    break;
                case 2:
                    s.push(snode);
                    snode.first = snode.first->right;
                    snode.second = 0;
                    break;*/
                case 0:
                    s.push(snode);
                    snode.first = snode.first->left;
                    snode.second = 0;
                    break;
                case 1:
                    ans.push_back(snode.first->val);
                    ++snode.second;
                    break;
                case 2:
                    s.push(snode);
                    snode.first = snode.first->right;
                    snode.second = 0;
                    break;
                default:
                    break;
            }
        } 
    }
    vector<int> inorderTraversal(TreeNode* root) {
        ans.clear();
        invisit(root);
        return ans;
    }
};

145. 二叉树的后序遍历

class Solution {
public:
    vector<int> ans;
    // 递归版本
    /*
    void povisit(TreeNode* r)
    {
        if(r)
        {
            povisit(r->left);
            povisit(r->right);
            ans.push_back(r->val);
        }
    }*/
    //非递归版本
    /*
    void povisit(TreeNode * r)
    {
        stack<pair<TreeNode*, int>> s;
        while(!s.empty() || r!=NULL)
        {
            while(r!=NULL)
            {
                s.push(make_pair(r,0));
                r = r->left;
            }
            if(!s.empty())
            {
                auto tmp = s.top();
                s.pop();
                if(tmp.second == 0)
                {
                    tmp.second = 1;
                    s.push(tmp);
                    r = tmp.first->right;
                }
                else
                {
                    ans.push_back(tmp.first->val);
                    r = NULL;
                }
            }
        }
    }*/
    // 通用非递归版本,借助于模拟编译器的栈
    void povisit(TreeNode *r)
    {
        if(r == NULL)
            return;
        stack<pair<TreeNode*, int>> s;
        auto snode = make_pair(r,0);
        while( 1 )
        {
            //snode.first == NULL 对应于左节点或者是右节点为空的情况。
            //snode.second >= 3 对应的是这个函数题中的代码顺序执行完了的情况 这样就可以直接回退,也就是出栈了。
            while(!s.empty() && (snode.first == NULL ||  snode.second >= 3))
            {
                snode = s.top();
                s.pop();
                ++snode.second;
            }
            //栈为空了 并且还处于这种状态,就说明已经处理完了,退出循环就行了
            if(snode.first == NULL || snode.second >= 3)
            {
                break;
            }
            //状态转移 就是所写的递归代码
            switch( snode.second )
            {
                case 0:
                    s.push(snode);
                    snode.first = snode.first->left;
                    snode.second = 0;
                    break;
                case 1:
                    s.push(snode);
                    snode.first = snode.first->right;
                    snode.second = 0;
                    break;
                case 2:
                    ans.push_back(snode.first->val);
                    ++snode.second;
                    break;
                default:
                    break;
            }
        } 
    }
    
    vector<int> postorderTraversal(TreeNode* root) {
        ans.clear();
        povisit(root);
        return ans;
    }
};

猜你喜欢

转载自www.cnblogs.com/randyniu/p/9194667.html
今日推荐