二叉树前序/中序/后序遍历非递归实现

  1. 前序遍历
    leetcode144

    前序遍历递归过程如下:

    void inorderTraversal(TreeNode* root){
        if(root==nullptr)
            return root;
        cout<<root->val<<endl;
        inorderTraversal(root->left);
        inorderTraversal(root->right);
    }

    非递归
    执行用时 :4 ms, 在所有 C++ 提交中击败了83.78%的用户

    内存消耗 :9 MB, 在所有 C++ 提交中击败了91.93%的用户

    思路如下:前序遍历是根-左-右,把根也看成左孩子,cout<<root->val<<endl;inorderTraversal(root->left);就是不断存储数据以及不断访问左结点的过程,对应到while循环就是,存储当前结点,并入栈,继续访问左结点,直到左结点为空;inorderTraversal(root->right)可以看成是把当前右结点看成新的根节点,重新开启while循环的过程,对应的就是,t=S.top();S.pop();t=t->right;由于栈顶数据已经存储,所以需要出栈,再对右子树进行循环操作。
        vector<int> preorderTraversal(TreeNode* root) {
            vector<int> result;
            if(root==nullptr)
                return result;
            TreeNode* t=root;
            stack<TreeNode*> S;
            while(t || !S.empty()){
                while(t){
                    result.push_back(t->val);
                    S.push(t);
                    t=t->left;
                }
                t=S.top();
                S.pop();
                t=t->right;
            }
            return result;
        }

     

  2. 中序遍历
    leetcode94

    树的递归访问过程如下:

    void inorderTraversal(TreeNode* root){
        if(root==nullptr)
            return root;
        inorderTraversal(root->left);
        cout<<root->val<<endl;
        inorderTraversal(root->right);
    }

    非递归
    执行用时 :4 ms, 在所有 C++ 提交中击败了83.74%的用户

    内存消耗 :9.1 MB, 在所有 C++ 提交中击败了64.58%的用户
    思路:中序遍历:左-根-右,inorderTraversal(root->left)这一语句可以借助一个while循环,不断把左孩子入栈,直到左孩子为空;cout<<root->val<<endl这一语句就是读取数据的过程,对应的就是t=S.top();result.push_back(t->val);S.pop();inorderTraversal(root->right)这一语句就是将右子树进行重复操作,那就是将右孩子看成新的根节点,重新开启while循环的过程,t=t->right;直到当前结点为空且栈也为空。

        vector<int> inorderTraversal(TreeNode* root) {
            vector<int> result;
            if(root==nullptr)
                return result;
            stack<TreeNode*> S;
            TreeNode* t=root;
            while(t || !S.empty()){
                while(t){
                    S.push(t);
                    t=t->left;
                }
                t=S.top();
                result.push_back(t->val);
                S.pop();
                t=t->right;
            }
            return result;
        }

     

  3. 后序遍历
    后序遍历是左-右-根,后序遍历比较难做一些,但是,前序遍历好做啊,而两者又有相近之处,所以我们应该想着把后序遍历转换成前序遍历。推导一下就是,按照根据根-右-左的方式前序遍历,将数据入栈,那么栈低到栈顶数据顺序就是:根-右-左,存储完毕,将栈中数据出栈到向量后,向量里数据的顺序就是:左-右-根。
    借助两个栈完成,一个栈跟前面前序遍历的作用相同,一个栈用来存储数据。

    执行用时 :4 ms, 在所有 C++ 提交中击败了82.57%的用户

    内存消耗 :9.3 MB, 在所有 C++ 提交中击败了31.72%的用户

        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> result;
            if(root==nullptr)
                return result;
            stack<TreeNode*> S1;
            stack<int>S2;
            TreeNode *t=root;
            while(t || !S1.empty()){
                while(t){
                    S2.push(t->val);//存储数据
                    S1.push(t);
                    t=t->right;
                }
                t=S1.top();
                S1.pop();
                t=t->left;
            }
            while(!S2.empty()){
                result.push_back(S2.top());
                S2.pop();
            }
            return result;
        }

    关键是要能以正确的逻辑理解和分析问题,才能使用代码简洁地描述心中所想。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是递归与非递归实现二叉树前序中序后序遍历算法代码。 ```python # 定义二叉树结构体 class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right # 递归实现前序遍历 def preorder_recursive(root): if not root: return [] return [root.val] + preorder_recursive(root.left) + preorder_recursive(root.right) # 非递归实现前序遍历 def preorder_non_recursive(root): if not root: return [] res, stack = [], [root] while stack: node = stack.pop() res.append(node.val) if node.right: stack.append(node.right) if node.left: stack.append(node.left) return res # 递归实现中序遍历 def inorder_recursive(root): if not root: return [] return inorder_recursive(root.left) + [root.val] + inorder_recursive(root.right) # 非递归实现中序遍历 def inorder_non_recursive(root): if not root: return [] res, stack, node = [], [], root while stack or node: while node: stack.append(node) node = node.left node = stack.pop() res.append(node.val) node = node.right return res # 递归实现后序遍历 def postorder_recursive(root): if not root: return [] return postorder_recursive(root.left) + postorder_recursive(root.right) + [root.val] # 非递归实现后序遍历 def postorder_non_recursive(root): if not root: return [] res, stack = [], [root] while stack: node = stack.pop() if node.left: stack.append(node.left) if node.right: stack.append(node.right) res.append(node.val) return res[::-1] ``` 这里给出了二叉树前序中序后序遍历的递归实现非递归实现,其中非递归实现使用了栈来实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值