今天是记录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;
}