二叉树的先序,中序和后序遍历,java语言非递归实现

//定义一棵二叉树
public class MyTreeNode {
    public int val;
    public MyTreeNode left;
    public MyTreeNode right;
    public MyTreeNode() {}
    public MyTreeNode(int val) { this.val = val; }
    public MyTreeNode(int val, MyTreeNode left, MyTreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
public void preorderTraversal(MyTreeNode root) {
        //先序遍历的非递归算法
        /*
        先定义一个栈,将根节点入栈。然后当栈非空时循环出栈,出栈后访问之
        然后,如果右孩子非空,则右孩子入栈,左孩子非空,左孩子入栈。
        循环下去,直至栈空,则二叉树所有结点也访问完毕
         */
        Stack<MyTreeNode> stack = new Stack<>();
   
        MyTreeNode ele = new MyTreeNode();
       
        if (root != null) {
            stack.push(root);
            while (!stack.isEmpty()) {
                ele = stack.pop();
                visit(ele);//visit是访问逻辑,自定义。
                //先让右孩子入栈
                if (ele.right != null) stack.push(ele.right);
                if (ele.left != null) stack.push(ele.left);
            }
        }
    }
//中序遍历
public void  inorderTraversal(MyTreeNode root) {
        if (root != null) {
            Stack<MyTreeNode> stack = new Stack<>();
            //如果有左孩子,一直入栈
            MyTreeNode p = root;
            while (p != null) {
                stack.push(p);
                p = p.left;
            }
            //将stack中的元素一个个出栈
            while (!stack.isEmpty()) {
                //将栈顶元素弹出
                MyTreeNode node = stack.pop();
                visit(node);
                //如果该出栈的元素还有右孩子,则将该右孩子和以右孩子为根节点的所有左孩子入栈
                if (node.right != null) {
                    p = node.right;
                    while (p != null) {
                        stack.push(p);
                        p = p.left;
                    }
                }
            }
        }
    }
/* 后序遍历。
       后续遍历得到的顺序的逆顺序恰好是先序遍历时左右子树颠倒的结果。
       所以先按照左右颠倒的先序遍历来遍历二叉树,将结果压入一个栈中,然后弹出就是后续遍历的顺序了
        */
    public void postorderTraversal(MyTreeNode root) {
        MyTreeNode ele =new MyTreeNode();
        Stack<MyTreeNode> stack = new Stack<>();
        Stack<MyTreeNode> stack2 =new Stack<>();
        if (root != null) {
            stack.push(root);
            while (!stack.isEmpty()) {
                ele = stack.pop();
                stack2.push(ele);
                //为了颠倒左右子树的遍历顺序,先将左子树入栈。
                if (ele.left != null) stack.push(ele.left);
                if (ele.right != null) stack.push(ele.right);
            }
            while (!stack2.isEmpty()) visit(stack2.pop().val);
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值