二叉树的层序遍历

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

来源:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
基本思路:这里通过队列实现迭代来实现的
1、定义一个队列,用于存放节点
2、判断队列是否为空,如果不为空,那么首先获取当前队列中的节点个数,然后再就从队列中跳出一个节点,然后通过判断这个节点左右子节点是否为null,从而可以知道是否要将它的左右子节点压入队列中,但是值得注意的是,必须要获取当前队列中的节点个数,从而可以知道每从队列中跳出一个节点时,往集合中添加的节点之前有多少个节点
3、重复步骤2,直到队列为空
节点类:

public class Node {
    public int value;
    public Node left;
    public Node right;
    public Node(int value){
        this.value = value;
    }

    @Override
    public String toString() {
        return value+" ";
    }
}

测试类:

/**
 * 二叉树的层序遍历(即从左到右进行输出,并且逐层访问
 * 基本思路:通过队列实现迭代,从而实现二叉树的层序遍历
 * 1、将根节点压入到队列中
 * 2、之后,将从队列中跳出一个节点,并且判断这个新跳出节点的左右子节点是否为空,如果为空,就不要
 * 将其压入到队列中去,否则就将其压入队列中
 * 3、重复2操作,知道队列为空
 */
public class TreeCenXuDisplay {
    public static List<List<Integer>> list = new ArrayList<>();
    public int[] arr = {4,5,8,10,12,15,18};//通过中序遍历得到的数组来构建二叉树
    public static void main(String[] args) {
        TreeCenXuDisplay test = new TreeCenXuDisplay();
        Node root = test.buildTree(0,test.arr.length);
        System.out.print("通过中序遍历得到的二叉树的前序遍历: ");
        test.display(root);
        System.out.println();
        System.out.println("二叉树的层序遍历: ");
        test.display2(root);
        for (List<Integer> list2: list) {
            System.out.println(list2);
        }
    }

    /**
     * 将一个按照升序排列的有序数组(即二叉树中序遍历得到的),转换为一棵高度平衡二叉搜索树。
     *本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
     * @param start
     * @param end
     */
    public Node buildTree(int start, int end) {
        if(start >= end){
            /**
             * 如果范围不正确的时候,结束递归,注意这里必须要有=,因为end一开始传递的参数时数组的长度,此时
             * end - start表示的是数组的长度,此时如果start = end是,表示的是有0个元素,所以结束递归,
             * start > end就更不用说了
             */
            return null;
        }
        int mid = (start + end) / 2;//数组中间或者中间偏一个节点是根节点
        Node root = new Node(arr[mid]);//新建一个根节点
        //构建左子树、右子树
        root.left = buildTree(start,mid);
        root.right = buildTree(mid + 1,end);
        return root;
    }

    /**
     * 树的前序遍历
     */
    public void display(Node root) {
          if(root == null){
              return;
          }
          System.out.print(root + " ");
          display(root.left);
          display(root.right);
    }

    /**
     * 树的层序遍历:通过一个队列实现迭代,从而实现层序遍历
     * 基本思路:
     * 1、定义一个队列,用于存放节点
     * 2、判断队列是否为空,如果不为空,那么首先获取当前队列中的节点个数,然后再就从队列中跳出一个节点,然后通过判断这个
     * 节点左右子节点是否为null,从而可以知道是否要将它的左右子节点压入队列中,但是值得注意的是,必须要获取当前队列中的节点个数,从而可以知道每从队列中跳出一个节点时,往集合中添加的节点有多少个
     * 3、重复步骤2,知道队列为空
     */
    public void display2(Node root){
        //定义一个队列
        Queue<Node> queue = new LinkedList<>();
        //定义一个集合
        ArrayList<Integer> arrayList = null;
        //将根节点添加到队列中
        queue.offer(root);
        //通过判断队列是否为空,从而将其左右子节点添加到队列中
        while(!queue.isEmpty()){
            arrayList = new ArrayList<>();
            //获取当前队列中的节点个数
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                //注意的是,这里的循环条件不可以时queue.size,否则就会发生报错
                //将队列中跳出一个根节点,并将其对应的值添加到集合arrayList中
                root = queue.poll();
                arrayList.add(root.value);
                //判断当前根节点的左右子节点是否为空,如果不为空,就添加到队列中
                if(root.left != null){
                    queue.offer(root.left);
                }
                if(root.right != null){
                    queue.offer(root.right);
                }
            }
            list.add(arrayList);//将一个集合添加到list中
        }
    }
}

运算结果:
在这里插入图片描述
值得注意的是,构造层序遍历的代码不可以是这样子的,即不可以是单层循环:

/**
     * 这里没有直到每一层中的节点个数,并且只是单层循环,那么每一次只能向队列中添加两个节点
     * 所以需要有嵌套循环,并且第二层循环的循环条件是要直到每一层中节点个数,即队列的节点个数
     * @param root
     */
    private void display3(Node root) {
        //新建一个队列
        Queue<Node> queue = new LinkedList<>();
        //新建一个集合
        ArrayList<Integer> arrayList = new ArrayList<>();
        //将根节点压入到对了中
        queue.offer(root);
        arrayList.add(root.value);
        list.add(arrayList);
        while(!queue.isEmpty()){
            arrayList = new ArrayList<>();
            root = queue.poll();//从队列中跳出根节点
            //判断它的左右子节点是否为空,如果不为空,就添加到队列中
            if(root.left != null){
                queue.offer(root.left);
                arrayList.add(root.left.value);
            }
            if(root.right != null){
                queue.offer(root.right);
                arrayList.add(root.right.value);
            }
            list.add(arrayList);
        }
    }

否则对应的错误结果是这样的:
在这里插入图片描述
也正如此,所以需要通过循环嵌套实现二叉树的层序遍历,并且需要直到每一层的节点个数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值