二叉树的非递归遍历——易记版

在力扣上做题的时候发现了大佬给的二叉树非递归遍历的模板,前中后序只需要套用一个模板就行了,非常好记。原版本是C++写的,链接如下:

作者:sonp
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/mo-fang-di-gui-zhi-bian-yi-xing-by-sonp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以下用java实现,其中的注释也与原版相同。

思路

需要一个标志区分每个递归调用栈,这里使用 nullptr 来表示。

Java代码

先序遍历

访问顺序为中、左、右,入栈顺序为右、左、中。

public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> output = new ArrayList<>();  //保存结果
        LinkedList<TreeNode> stack = new LinkedList<>();  //调用栈
        if(root == null) return output;  

        stack.add(root);  //首先入栈root节点
        TreeNode temp;
        while(!stack.isEmpty()){
            temp = stack.pollLast();  //访问过的节点弹出
            if(temp != null){
                if(temp.right != null) stack.add(temp.right);  //右节点先压栈,最后处理
                if(temp.left != null) stack.add(temp.left);
                stack.add(temp);  //当前节点重新压栈(留着以后处理),因为先序遍历所以最后压栈
                stack.add(null);  //在当前节点之前加入一个空节点表示已经访问过了
            }
            else{//空节点表示之前已经访问过了,现在需要处理除了递归之外的内容
                temp = stack.pollLast();  //temp是null之前压栈的一个节点,也就是上面stack.add(temp)中的那个temp
                output.add(temp.val);  //处理当前节点
            }
        }
        return output;
    }
中序遍历

访问顺序为左、中、右,入栈顺序为右、中、左。
只有注释的地方的顺序改了,哈哈是不是很好记,为大佬点赞。

public List<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> output = new ArrayList<>();
        LinkedList<TreeNode> stack = new LinkedList<>();
        if(root == null) return output;

        stack.add(root);
        TreeNode temp;
        while(!stack.isEmpty()){
            temp = stack.pollLast();
            if(temp != null){
                if(temp.right != null) stack.add(temp.right);
                stack.add(temp);  //在左节点之前重新插入该节点,以便在左节点之后处理(访问值)
                stack.add(null);  null跟随temp插入,标识已经访问过,还没有被处理
                if(temp.left != null) stack.add(temp.left);
            }
            else{
                temp = stack.pollLast();
                output.add(temp.val);
            }
        }
        return output;
    }
后序遍历

访问顺序为左、右、中,入栈顺序为中、左、右。

public List<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> output = new ArrayList<>();
        LinkedList<TreeNode> stack = new LinkedList<>();
        if(root == null) return output;

        stack.add(root);
        TreeNode temp;
        while(!stack.isEmpty()){
            temp = stack.pollLast();
            if(temp != null){
                stack.add(temp);  //在右节点之前重新插入该节点,以便在最后处理(访问值)
                stack.add(null);  //nullptr跟随t插入,标识已经访问过,还没有被处理
                if(temp.right != null) stack.add(temp.right);
                if(temp.left != null) stack.add(temp.left);
            }
            else{
                temp = stack.pollLast();
                output.add(temp.val);
            }
        }
        return output;
    }
对比中序遍历的递归写法
void dfs(t){ //进入函数表示“访问过”,将t从栈中弹出

    dfs(t->left);   //因为要访问t->left, 所以我先把函数中下面的信息都存到栈里。
                //依次call.push(t->right), call.push(t)【t第二次入栈】, call.push(nullptr)【标识t二次入栈】, call.push(t->left)。
                //此时t并没有被处理(卖萌)。栈顶是t->left, 所以现在进入t->left的递归中。

    //res.push_back(t->val)
    t.卖萌();   //t->left 处理完了,t->left被彻底弹出栈。
                //此时栈顶是nullptr, 表示t是已经访问过的。那么我现在需要真正的处理t了(即,执行卖萌操作)。
                //卖萌结束后,t 就被彻底弹出栈了。
    

    dfs(t->right); 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java二叉树非递归遍历可以通过使用栈数据结构来实现。首先,我们创建一个空的栈,将根节点入栈。然后,我们进入一个循环,直到栈为空为止。在每一次循环中,我们弹出栈顶元素,并将其访问。接下来,如果该节点有右子节点,则将右子节点入栈。如果该节点有左子节点,则将左子节点入栈。由于栈是先进后出的数据结构,所以我们先入栈右子节点,再入栈左子节点,以确保在遍历过程中先访问左子树节点。这样就能够实现二叉树非递归遍历。 以下是一个示例代码实现二叉树非递归中序遍历: ```java public void inorderTraversal(Node root) { if (root == null) { return; } Stack<Node> stack = new Stack<>(); Node current = root; while (current != null || !stack.isEmpty()) { while (current != null) { stack.push(current); current = current.leftChild; } current = stack.pop(); System.out.print(current.data + " "); // 访问节点 current = current.rightChild; } } ``` 在这个示例代码中,我们首先判断当前节点是否为空或者栈是否为空,如果不满足则进入循环。在循环内部,我们首先将当前节点及其所有左子节点入栈,直到当前节点为空。然后,我们弹出栈顶节点并访问该节点。最后,将当前节点更新为其右子节点,并继续下一次循环。 通过这种方式,我们可以实现二叉树非递归中序遍历。你可以根据需要修改代码实现其他类型的非递归遍历,比如前序遍历和后序遍历。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [用Python实现二叉树二叉树非递归遍历及绘制的例子](https://download.csdn.net/download/weixin_38618784/14869891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [java实现二叉树树的非递归遍历](https://blog.csdn.net/weixin_41826973/article/details/105555647)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值