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;
    }
};

原文地址:https://www.cnblogs.com/randyniu/p/9194667.html

时间: 2024-10-09 23:40:17

Binary Tree Traversal In Three Ways In Leetcode的相关文章

C++ Binary Tree Traversal

关于二叉树的遍历有很多的方法, 下面介绍两个经典的遍历算法: BFS和DFS.一个是深度优先遍历, 一个是广度有优先遍历. 这两种遍历算法均属于盲目的遍历算法, 一般而言, 启发式的遍历搜索算法比较好一些. . 关于各种遍历算法的对比, 将会在后面逐一提及. 这里不在赘述. 由于树是一个非线性的数据结构, 显然不能像linked list , 或者Array那样通过从头像最末尾移动去实现遍历每一个元素, 我们使用的是BFS和DFS算法. 例如下面的一个二叉树: 所谓的树遍历(Tree trave

LeetCode—— Binary Tree Traversal

二叉树遍历的三道题 Binary Tree Preorder Traversal Binary Tree Inorder Traversal Binary Tree Postorder Traversal LeetCode 上二叉树的节点定义如下: // 树的节点 struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {

【Leetcode】Binary Tree Traversal

把三个二叉树遍历的题放在一起了. 递归写法太简单,就不再实现了,每题实现了两种非递归算法. 一种是利用栈,时间和空间复杂度都是O(n). 另一种是借助线索二叉树,也叫Morris遍历,充分利用树中节点的空指针域. 先序: Binary Tree Preorder Traversal Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binary tree {1,#,

Binary Tree Traversal

1. Preorder Tree Traversal 1 // Solution 1. With Stack 2 // Time Complexity : O(n) 3 // Space Complexity: O(h) ~ O(log n) 4 public class Solution { 5 public List<Integer> preorderTraversal(TreeNode root) { 6 ArrayList<Integer> list = new Array

Binary Tree Traversal Algorithms (二叉树遍历算法)

本文共列出了11个常见的二叉树遍历算法.二叉树的遍历主要有深度优先遍历和广度优先遍历.深度优先遍历包含前序遍历.中序遍历和后序遍历. 值得一提的是, 其中的 Morris 算法 可以线性时间不需要额外空间(用户栈或系统栈空间)实现二叉树的前序遍历.中序遍历和后序遍历.关于Morris算法, 可参考 http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html 算法清单: A1. A2. A3, 分别是中序遍历的递归

Binary Tree Traversal 二叉树的前中后序遍历

[抄题]: [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图]: [一刷]: [二刷]: [三刷]: [四刷]: [五刷]: [总结]: [复杂度]:Time complexity: O() Space complexity: O() [英文数据结构,为什么不用别的数据结构]: [其他解法]: [Follow Up]: [L

[lintcode easy]Binary Tree Postorder Traversal

Binary Tree Postorder Traversal Given a binary tree, return the postorder traversal of its nodes' values. Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Challenge Can you do it without recursion? Among preorder,inorder and postorder binary tree

LeetCode 145 Binary Tree Postorder Traversal(二叉树的后续遍历)+(二叉树、迭代)

翻译 给定一个二叉树,返回其后续遍历的节点的值. 例如: 给定二叉树为 {1, #, 2, 3} 1 2 / 3 返回 [3, 2, 1] 备注:用递归是微不足道的,你可以用迭代来完成它吗? 原文 Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Note: Recur

LeetCode Binary Tree Inorder Traversal

LeetCode解题之Binary Tree Inorder Traversal 原题 不用递归来实现树的中序遍历. 注意点: 无 例子: 输入: {1,#,2,3} 1 2 / 3 输出: [1,3,2] 解题思路 通过栈来实现,从根节点开始,不断寻找左节点,并把这些节点依次压入栈内,只有在该节点没有左节点或者它的左子树都已经遍历完成后,它才会从栈内弹出,这时候访问该节点,并它的右节点当做新的根节点一样不断遍历. AC源码 # Definition for a binary tree node