二叉树的遍历方式-递归及非递归实现

二叉树的节点表示

首先,要完成二叉树的方式,要先定义二叉树的节点,节点定义如下:

class Node {
    char value;
    Node left;
    Node right;

    public Node(char value) {
        this.value = value;
    }
}

二叉树的前序遍历

二叉树的前序遍历:先遍历根节点,再遍历左子树,最后遍历右子树。

1.递归实现二叉树的前序遍历

每次遍历都是根-左子树-右子树的方式。
因此我们使用递归来完成,递归就是有终止条件,并且调用自己。
这里的终止条件就是当遍历的节点为空时,结束。

  public  void preOrderTraveral (Node root){
        if(root == null){
            return;
        }
        System.out.print(root.value + " ");
        preOrderTraveral(root.left);
        preOrderTraveral(root.right);
    }

2.非递归实现二叉树的前序遍历

利用栈实现::从根节点开始,先遍历根节点,并输出,取栈顶,去遍历左孩子,并输出。当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,右孩子直至孩子全部遍历结束。

 void preOrderTraversal2(Node root) {
        Stack<Node> stack = new Stack<>();
        Node cur = root;
        while(cur != null || !stack.empty()) {
            while (cur != null) {
                stack.push(cur);
                System.out.print(cur.value + " ");
                cur = cur.left;
            }
            cur = stack.pop();
            cur = cur.right;
        }
    }

3.利用集合实现二叉树的先序遍历

 public List<Character> preorderTraversal3(Node root) {
        List<Character> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        //System.out.print(root.value + " ");
        list.add(root.value);
        List<Character> left = preorderTraversal3(root.left);
        list.addAll(left);
        List<Character> right = preorderTraversal3(root.right);
        list.addAll(right);
        return list;
    }

二叉树的中序遍历

二叉树的前序遍历:先遍历左子树,再遍历根节点,最后遍历右子树。

1.递归实现

  void inOrderTraversal(Node root) {
        if(root == null){
            return;
        }
        inOrderTraversal(root.left);
        System.out.print(root.value + " ");
        inOrderTraversal(root.right);
    }

2.非递归实现,利用栈

 void inOrderTraversal2(Node root) {
        Stack<Node> stack = new Stack<>();
        Node cur = root;
        while (cur != null || !stack.empty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            System.out.print(stack.peek().value + " ");
            cur = stack.pop();
            cur = cur.right;
        }
    }

3.利用集合实现:

public List<Character> inorderTraversal3(Node root) {
        List<Character> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        List<Character> left = inorderTraversal3(root.left);
        list.addAll(left);
        list.add(root.value);
        List<Character> right = inorderTraversal3(root.right);
        list.addAll(right);
        return list;
    }

二叉树的后序遍历

后序遍历递归定义:先左子树,后右子树,再根节点。

1.递归实现二叉树的后序遍历:

 void postOrderTraversal(Node root) {
        if(root == null){
            return;
        }
        postOrderTraversal(root.left);
        postOrderTraversal(root.right);
        System.out.print(root.value + " ");
    }

2.非递归实现,利用栈:

后序遍历的难点在于:需要判断上次访问的节点是位于左子树,还是右子树。若是位于左子树,则需跳过根节点,先进入右子树,再回头访问根节点;若是位于右子树,则直接访问根节点。

 void postOrderTraversal2(Node root) {
        Stack<Node> stack = new Stack<>();
        Node cur = root;
        Node tmp = null;
        while (cur != null || !stack.empty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.peek();
            if(cur.right == null || cur.right == tmp) {
                System.out.print(stack.pop().value + " ");
                tmp = cur;
                cur = null;
            }else {
                cur = cur.right;
            }
        }
    }

3.利用集合实现后序遍历

 public List<Character> postorderTraversal3(Node root) {
       List<Character> list = new ArrayList<>();
       if(root == null){
           return list;
       }
       List<Character> left = postorderTraversal3(root.left);
       list.addAll(left);
       List<Character> right = postorderTraversal3(root.right);
       list.addAll(right);
       //System.out.println(root.value + " ");
       list.add(root.value);
       return list;
   }

二叉树的层序遍历

1.利用队列实现

void levelOrderTraversal(Node root){
        Queue<Node> queue = new LinkedList<>();
        if(root != null){
            queue.offer(root);
        }
        while(!queue.isEmpty()){
            Node cur = queue.peek();
            if(cur == null){
                return;
            }
            System.out.print(cur.value + " ");
            queue.poll();
            if(cur.left != null){
                queue.offer(cur.left);
            }
            if(cur.right != null){
                queue.offer(cur.right);
            }
        }
    }

2.利用List集合实现

 public List<List<Character>> levelOrder(Node root) {
        List<List<Character>> ret = new ArrayList<>();
        Queue<Node> queue = new LinkedList<>();
        if(root != null){
            queue.offer(root);
        }
        //队列的元素,也就是一层数据
        while(!queue.isEmpty()){
            int count  = queue.size();
            //存放的是一层数据
            List<Character> list = new ArrayList<>();
            while(count > 0){
                Node cur = queue.poll();
                //System.out.print(cur.value + " ");
                list.add(cur.value);
                if(cur.left != null){
                    queue.offer(cur.left);
                }
                if(cur.right != null){
                    queue.offer(cur.right);
                }
                count--;
            }
            ret.add(list);
        }
        return ret;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值