程序员代码面试指南第二版 32.分别用递归和非递归方式实现二叉树先序、中序和后序遍历

welcome to my blog

程序员代码面试指南第二版 32.分别用递归和非递归方式实现二叉树先序、中序和后序遍历

题目描述
分别按照二叉树先序,中序和后序打印所有的节点。

输入描述:
第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。

以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)

输出描述:
输出三行,分别表示二叉树的先序,中序和后序。

示例1

输入
3 1
1 2 3
2 0 0
3 0 0

输出
1 2 3
2 1 3
2 3 1
第一次做; 必须掌握的基础; 注意如果建立树; 超时,通过75%
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String[] str = sc.nextLine().split(" ");
        int n = Integer.parseInt(str[0]);
        int rootVal = Integer.parseInt(str[1]);
        //创建二叉树
        TreeNode[] nodes = new TreeNode[n+1];
        for(int i=1; i<=n; i++){
            nodes[i] = new TreeNode(i);
        }
        for(int i=0; i<n; i++){
            str = sc.nextLine().split(" ");
            int cur = Integer.parseInt(str[0]);
            int left = Integer.parseInt(str[1]);
            int right = Integer.parseInt(str[2]);
            nodes[cur].left = left==0?null:nodes[left];
            nodes[cur].right = right==0?null:nodes[right];
        }
        //
        TreeNode root = nodes[rootVal];
        preOrder(root);
        inOrder(root);
        posOrder2(root);
    }
    /*
    1.root入栈stack
    2.s不为空时,
        弹出栈顶元素node并打印
        node的右左孩子(如果有的话)入栈
    */
    public static void preOrder(TreeNode root){
        if(root==null)
            return;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            System.out.print(node.val+" ");
            if(node.right!=null)
                stack.push(node.right);
            if(node.left!=null)
                stack.push(node.left);
        }
        System.out.println();
    }
    /*
    大原则:压入cur为根节点的子树的左边界
    1.栈不为空或者cur不为null时
        cur!=null时,不断压入左孩子
        cur==null时,弹出栈顶元素nod并打印, cur指向node.right,重复上一行过程
    */
    public static void inOrder(TreeNode root){
        if(root==null)
            return;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while(!stack.isEmpty() || cur!=null){
            if(cur!=null){
                stack.push(cur);
                cur = cur.left;
            }
            else{
                TreeNode node = stack.pop();
                System.out.print(node.val+" ");
                cur = node.right;
            }
        }
        System.out.println();
    }
    /*
    使用两个栈的方法
    大原则:从右往左, 将树的右边界压入stack2
    1.root入栈stack1
    2.当stack1不为空时,
        弹出栈顶元素cur, 将cur的左右孩子(如果有的话)压入stack1, 将cur压入stack2
    3.当stack2不为空时,
        弹出栈顶元素并打印
    */
    public static void posOrder1(TreeNode root){
        if(root==null)
            return;
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(root);
        while(!stack1.isEmpty()){
            TreeNode node = stack1.pop();
            if(node.left!=null)
                stack1.push(node.left);
            if(node.right!=null)
                stack1.push(node.right);
            stack2.push(node);
        }
        while(!stack2.isEmpty()){
            System.out.print(stack2.pop().val+" ");
        }
        System.out.println();
    }

    /*
    使用一个栈的方法
    两个指针:c=null,指向栈顶元素; h=root,指向最近一次弹出并打印的节点
    1.root入栈stack
    2.当stack不为空时
        c指向栈顶元素
        如果c.left!=null && h!=c.left && h!=c.right时, 将c.left压入stack
        如果c.right!=null && h!=c.right时, 将c.right压入stack
        如果不满足上面的条件,则弹出栈顶元素并打印, 令h=c
    */
    public static void posOrder2(TreeNode root){
        if(root==null)
            return;
        TreeNode c=null, h=root;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            c = stack.peek();
            //核心:h==c.left或者h==c.right时,说明c.left已经被打印过了,就不用再把c.left压入stack了
            if(c.left!=null && h!=c.left && h!=c.right)
                stack.push(c.left);
                //核心:h==c.right说明c.right已经被打印过了,就不用再把c.right压入stack了
            else if(c.right!=null && h!=c.right)
                stack.push(c.right);
            else{
                System.out.print(stack.pop().val+" ");
                h = c;
            }
        }
        System.out.println();
    }


    public static class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int val){
            this.val = val;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值