LeetCode -- 二叉树层序遍历

100 阅读2分钟

今天是记录leetcode刷题的第四天,今天的问题是二叉树的层序遍历。

二叉树是一个很重要的数据结构,是很多问题抽象的实体表现,而且其存储结构简单。

之前做过一个二叉树的前中后序遍历的题,二叉树的层序遍历算是这个问题的进阶版。 想要将二叉树按层级遍历,我们就需要将每一层的节点放到一起遍历,但是由于每一层的节点之间基本没有太大的关系,所以我们不能找同级节点之间的关联关系,我们只能从树得角度去思考。

由于我们能在根节点获取第一层的节点,再根据第一层的节点可以在获取第二层的节点,以此可以获取到最后一层。所以我们需要思考的是如何获取每一层的节点,这就需要引出BFS(广度优先搜索算法) 了。

BFS

广度优先搜索算法,也称宽度优先搜索算法,迪杰斯特拉算法使用了和广度优先搜索类似的思想,它可以系统的扫描树中的所有节点。

实现

  • 广度优先搜索的实现需要借助队列。初始化将根节点放入队列。
  • 取出队列的头部元素,将其下一级元素放到队列的尾部,同时标计该节点已被搜索。
  • 处理节点的值,如果到结束还没完成则结束。

广度优先搜索的思想还算简单,其实现也比较简单:

public List<List<Integer>> levelOrder(Node root) {
    // 这是一个典型的广度优先搜索,广度优先搜索使用队列实现,队列中存放节点
    if (root == null) {
        return new ArrayList<List<Integer>>();
    }
    List<List<Integer>> rt = new ArrayList<>();
    // 声明广度优先搜索的队列
    Queue<Node> queue = new ArrayDeque<>();
    // 根节点放入队列,注意offer和add没有太大的区别,只是一个不会抛出异常,一个会抛出异常
    queue.offer(root);
    // queue.add(root);

    // 循环队列
    while (!queue.isEmpty()) {
        // 队列不为空,声明存放同级节点值的数组
        List<Integer> level = new ArrayList<>();
        // 队列的大小
        int size = queue.size();
        // 循环取出队列中的节点
        for (int i = 0; i < size; i++) {
            // 取出当前队列中的第一个节点
            Node cur = queue.poll();

            level.add(cur.val);
            // 接下来要做的就是将节点的子节点放入队列,然后将节点的值放入同级数组
            List<Node> children = cur.children;
            for (Node child : children) {
                if(child != null){
                    queue.offer(child);
                }
            }
        }
        rt.add(level);
    }
    return rt;
}