JAVA非递归遍历二叉树

参考 https://blog.csdn.net/xxxxxxxx00772299/article/details/109318495

先序和中序

从node开始不断压入左节点直到拿到最左边的叶子结点,出栈,每次出栈判断右节点是否为空,如果不为空,右节点为node,重复以上步骤。
可以看到,父节点和左节点是连续的,所以可以完成先序和中序,但后序需要一些处理。

  • 如果在入栈时进行输出,那么就是先序遍历
  • 如果在出栈时进行输出,那么就是中序遍历

两个方法基本相同,唯一差别就在输出位置。
while负责入栈,if负责出栈

	 public static void preShow(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        if(root==null||root.left==null&&root.right==null) return;
        while(!(stack.isEmpty()&&node==null)){
            while(node!=null){
                stack.push(node);
                System.out.println(node);
                node = node.left;
            }
            if(!stack.isEmpty()){
                node = stack.pop();
                node = node.right;
            }
        }
    }
    public static void inShow(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        if(root==null||root.left==null&&root.right==null) return;
        while(!(stack.isEmpty()&&node==null)){
            while(node!=null){
                stack.push(node);
                node = node.left;
            }
            if(!stack.isEmpty()){
                node = stack.pop();
                System.out.println(node);
                node = node.right;
            }
        }
    }

后序

在这里插入图片描述
如果按照上面的方法,在2出栈的后才能拿到3,但后序的顺序是132,所以要保证

  • 如果右子树不存在,或者右子树在访问过的情况下(visited),正常输出2。
  • 如果右子树存在,并且右子树未访问过,2在栈中,让右节点作为node,进行下一次循环。

代码只对if进行了改动

      public static void postShow(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
//        visited代表已经访问过的右子树
        TreeNode visited = null;
        if(root==null||root.left==null&&root.right==null) return;
        while(!(stack.isEmpty()&&node==null)){
            while(node!=null){
                stack.push(node);
                node = node.left;
            }
            if(!stack.isEmpty()){
                node = stack.pop();
                if (node.right == null||node.right == visited) {
                    System.out.println(node);
//                    此节点已经被访问
                    visited = node;
//                    右子树已经处理完毕或者为null,跳过入栈环节,下一次循环直接父节点出栈
                    node = null;
                }else{
//                    为下一次输出保留这个节点,下一次循环处理右子节点。
                   stack.push(node);
                   node = node.right;
                }

            }
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值