非递归实现二叉树的先中后序遍历

1. 先序遍历

1.1 思路

  • ①创建一个栈
  • ②将根节点入栈
  • ③取出栈顶元素并访问
  • ④将其右子树入栈,左子树入栈
  • ⑤回到③重复

1.2 代码

//这里先序遍历创建一个栈,根->右->左
public static void preOrder(TreeNode root){
    if(root==null){
        return;
    }
    Stack<TreeNode> stack=new Stack<>();
    stack.push(root);
    //栈为空时,对栈pop,会抛出异常,所以要进行判断
    while(!stack.isEmpty()){
        TreeNode cur=stack.pop();
        System.out.print(cur.val+" ");
        if(cur.right!=null){
            stack.push(cur.right);
        }
        if(cur.left!=null){
            stack.push(cur.left);
        }
    }
}

2. 中序遍历

2.1 思路

  • ①创建一个栈
  • ②创建一个引用cur,从根节点出发
  • ③cur一路向左,遇到非空的入栈,遇到空时,循环结束
  • ④取出栈顶元素并访问
  • ⑤让cur指向该节点的右子树,回到③继续执行

2.2 代码

public static void inOrder(TreeNode root){
    if(root==null){
        return;
    }
    Stack<TreeNode> stack=new Stack<>();
    TreeNode cur=root;
    stack.push(cur);
    while(true){
        while(cur.left!=null){
            cur=cur.left;
            stack.push(cur);
        }
        //循环结束,栈非空,取出栈顶元素访问
        // 并且让cur指向这个节点的右子树
        if(!stack.isEmpty()){
            TreeNode node=stack.pop();
            System.out.print(node.val+" ");
            if(node.right!=null){
                stack.push(node.right);
                cur=node.right;
            }
         }else{
             break;
        }
    }
}

3. 后序遍历

3.1 思路

  • ①创建一个栈
  • ②创建一个引用cur,从根节点出发
  • cur一路向左,遇到非空入栈,遇到空,首先做出以下两种判断,来判断栈顶元素能否被直接访问:
  • I 栈顶元素的右子树是否为空(因为后序遍历时,若右子树为空时,才能直接访问根节点)
  • II 栈顶元素的右子树是否被访问过(后序遍历的顺序: 左->右->根,右子树访问过了才能访问根节点)
  • ③上面两种情况都不满足,让cur指向栈顶元素的右子树并将其入栈,重复执行③

3.2 代码

public static void postOrder(TreeNode root){
    if(root==null){
        return;
    }
    Stack<TreeNode> stack=new Stack<>();
    stack.push(root);
    TreeNode cur=root;
    //prev记录上一个出栈的节点
    TreeNode prev=null;
    while(true){
        while(cur.left!=null){
            cur=cur.left;
            stack.push(cur);
        }
        if(!stack.isEmpty()){
            TreeNode node=stack.peek();
            if(node.right==null||node.right==prev){
                prev=node;
                System.out.print(node.val+" ");
                stack.pop();
            }else{
                stack.push(node.right);
                cur=node.right;
            }
        }else{
             break;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值