参考:nettee
题目
介绍DFS与BFS
DFS(深度优先搜索)和 BFS(广度优先搜索)就像孪生兄弟,提到一个总是想起另一个。然而在实际使用中,我们用 DFS 的时候远远多于 BFS。
在二叉树的遍历上,两者不同之处在于代码的简易程度不同和遍历的顺序不同。
遍历的顺序就是数字的顺序。
void dfs(TreeNode root) {
if (root == null) {
return;
}
dfs(root.left);
dfs(root.right);
}
void bfs(TreeNode root) {
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll(); // Java 的 pop 写作 poll()
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
会有以上的区别主要是因为,DFS用了递归的方式隐含地使用了系统的栈,我们不需要自己维护一个数据结构。如果只是简单地将二叉树遍历一遍,那么 DFS 显然是更方便的选择。
思路
所以,在本题中我们采用BFS来进行解题。
但我们只用BFS遍历是无法将结果分层的。
因此,我们需要稍微修改一下代码,在每一层遍历开始前,先记录队列中的结点数量 n(也就是这一层的结点数量),然后一口气处理完这一层的 n 个结点。
public List<List<Integer>> levelOrder(TreeNode root){
List<List<Integer>> result = new ArrayList<>();
Queue<TreeNode> queue = new ArrayDeque<>();
if (root != null) {
queue.add(root);
}
while (!queue.isEmpty()) {
//记录此次循环的次数,即这一层节点的数量
int n = queue.size();
//记录弹出的每层list
List<Integer> level = new ArrayList<>();
for(int i=0; i<n; i++){
TreeNode node = queue.poll();
//把这层弹出的元素(每个)放入level集合里
level.add(node.val);
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
//把这层弹出的元素(集合)放入result集合里
result.add(level);
}
return result;
}