二叉树的前序、中序、后序遍历,非递归java

二叉树的前序、中序、后序遍历,非递归java

核心思路是把每一个结点看成父节点,叶子结点是左右孩子是null的父结点。
前序遍历

思路:

使用一个栈来存储结点,以便回到之前的父结点。

不断往左子树深入并不断先打印值再入栈直到左叶子的空左孩子
弹出栈顶,将指针指向它的右孩子
循环1,2步骤直至栈为空且指针也为空(意思是当栈为空但指针不为空时,继续。比如当栈顶元素是二叉树的根节点时,就会出现这种情况,此时指针指向根结点的右孩子,但是栈为空)

    void preOrder(TreeNode root){
        if(root==null) return;
        Stack<TreeNode> s=new Stack<>();
        while (!s.isEmpty()||root!=null){
            while(root!=null){
                System.out.print(root.val+" ");
                s.push(root);
                root=root.left;
            }
            if(!s.isEmpty()){
                TreeNode t=s.pop();
                root=t.right;
            }
        }
    }

中序遍历

思路:

不断往左子树深入并不断入栈直到左叶子的空左孩子
弹出栈顶,打印值,并将指针指向它的右孩子
循环1,2步骤直至栈为空且指针也为空

     void inOrder(TreeNode root){
        if(root==null) return;
        Stack<TreeNode> s=new Stack<>();
        while (!s.isEmpty()||root!=null){
            while(root!=null){
                s.push(root);
                root=root.left;
            }
            if(!s.isEmpty()){
                TreeNode t = s.pop();
                System.out.print(t.val+" ");
                root=t.right;
            }
        }
    }

后续遍历

思路:

后续遍历稍微复杂一些,因为当左孩子完成打印并从栈中弹出父结点的时候,此时需要判断右孩子需不需要打印,有两种情况:

如果右孩子为空,或者右孩子已经完成了打印,则打印当前的结点
如果右孩子未打印过,则需要将右孩子入栈

这里设置一个指针last来标记上一次打印的结点,这样只要判断last是不是右孩子就知道右孩子打印过没有了

具体步骤为:

不断往左子树深入并不断入栈直到左叶子的空左孩子
弹出栈顶,如果右孩子为null或者last是右孩子,则打印当前值;如果不是,则将指针指向右孩子
循环1,2步骤直至栈为空且指针也为空

    void postOrder(TreeNode root){
        if(root==null) return;
        Stack<TreeNode> s=new Stack<>();
        TreeNode last=null;
        while (!s.isEmpty()||root!=null){
            while (root!=null){
                s.push(root);
                root=root.left;
            }
            if(!s.isEmpty()){
                TreeNode t=s.pop();
                if(t.right==null||last==t.right){
                    System.out.print(t.val+" ");
                    last=t;
                }else{//右孩子还没有打印过
                    s.push(t);//因为当前结点未打印,所以要重新放回去,等右孩子打印完之后回来打印
                    root=t.right;
                }
            }
        }
    }

原文链接:https://blog.csdn.net/ChaunceyChen/article/details/88592559

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值