二叉树递归遍历和非递归遍历

题目

用递归和非递归实现二叉树的前序遍历、中序遍历和后序遍历并打印出相应结果。

private  class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
}

解析

在递归调用时候系统自动给我们创建栈来存储数据,而使用非递归时候需要我们自己实现栈来存储数据。

实现

递归实现前序遍历
public void preOrder(TreeNode root){
        if (root == null){
            return;
        }

        System.out.print(root.val+" ");
        preOrder(root.left);
        preOrder(root.right);
}
非递归实现前序遍历

对任一节点p

  • 访问节点p,并将节点p入栈
  • 判断节点p的左孩子是否为空。若为空,则取栈顶节点并进行出栈操作,并将栈顶节点的右孩子置为当前的节点p,循环上面的操作;若不为空,则将p的左孩子置为当前的节点p,循环上面的操作;
  • 直到p为NULL并且栈为空,则遍历结束。
public void preorder(TreeNode root){

        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode temp = root;
        System.out.println("前序遍历:");
        while (temp != null || !stack.isEmpty()){

            while (temp != null){
                System.out.print(temp.val + " ");
                stack.push(temp);
                temp = temp.left;
            }

            if (!stack.isEmpty()){
                temp = stack.pop();
                temp = temp.right;
            }
        }
}
递归实现中序遍历
 public void inOrder(TreeNode root){
        if (root == null){
            return;
        }

        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
}
非递归实现中序遍历

对于任一节点p

  • 若其左孩子不为空,则将p入栈并将p的左孩子设为当前的p,然后对当前节点p再进行相同的处理
  • 若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶节点,然后将当前的p置为栈顶节点的右孩子
  • 直到p为null并且栈为空则遍历结束
public void inorder(TreeNode root){
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode temp = root;
        System.out.println("中序遍历:");
        while (!stack.isEmpty() || temp != null){
            while (temp != null){
                stack.push(temp);
                temp = temp.left;
            }

            if (!stack.isEmpty()){
                temp = stack.pop();
                System.out.print(temp.val+" ");
                temp = temp.right;
            }
        }
}
递归实现后序遍历
public void postOrder(TreeNode root){
        if (root == null){
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val+" ");
}
非递归实现后序遍历
  • 要保证根结点在左孩子和右孩子访问之后才能访问,因此对任一节点p,先将其入栈。
  • 如果p不存在左孩子和右孩子,则可以直接访问它;或者p存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该节点。若非上述两种情况,则将p的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
public void postorder(TreeNode root){
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode cur = null;//当前节点
        TreeNode pre = null;//前一个节点
        stack.push(root);
        System.out.println("后序遍历:");
        while (!stack.isEmpty()){
            cur = stack.peek();
            if ((cur.left == null && cur.right == null) || 
                    (pre != null && (pre == cur.left || pre == cur.right))){
                System.out.print(cur.val + " ");
                stack.pop();
                pre = cur;
            }else {
               if (cur.right != null){
                    stack.push(cur.right);
               }
               if (cur.left != null){
                    stack.push(cur.left);
               }
            }
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值