DFS(深度优先搜索)和 BFS(广度优先搜索)就像孪生兄弟,提到一个总是想起另一个。然而在实际使用中,我们用 DFS 的时候远远多于 BFS。那么,是不是 BFS 就没有什么用呢?
如果我们使用 DFS/BFS 只是为了遍历一棵树、一张图上的所有结点的话,那么 DFS 和 BFS 的能力没什么差别,我们当然更倾向于更方便写、空间复杂度更低的 DFS 遍历。不过,某些使用场景是 DFS 做不到的,只能使用 BFS 遍历。这就是本文要介绍的两个场景:「层序遍历」、「最短路径」。
var dfs = function (root){
if(root==null){
return;
}
dfs(root.left);
dfs(root.right);
}
var dfs = function(root){
let queue = [];
queue.push(root);
while(queue.length>0){
let node = queue.pop();
if(node.left!=null){
queu.push(node.left);
}
if(node.right!=null){
queue.push(node.right)
}
}
}
DFS 遍历的代码比 BFS 简洁太多了!这是因为递归的方式隐含地使用了系统的 栈,我们不需要自己维护一个数据结构。如果只是简单地将二叉树遍历一遍,那么 DFS 显然是更方便的选择。
- BFS之层序遍历
层序遍历就是将二叉树分层,每一层从左到右遍历
var dfs = function(root){
let queue = [];
queue.push(root);
while(!queue){
let n = queue.length;
for(let i=0;i<n;i++){
let node = queue.pop();
if(node.left!=null){
queue.push(node.left);
}
if(node.right!=null){
queue.push(node.right);
}
}
}
}
level order
var levelOrder = function(root){
let res = [];
let queue = [];
if(root!=null){
queue.push(root);
}
while(queue.length>0){
let n = queue.length;
let level = [];
for(let i=0;i<n;i++){
let node = queue.pop();
level.push(node.val);
if(node.left!=null){
queue.push(node.left);
}
if(node.right!=null){
queue.push(node.right);
}
}
res.push(level);
}
return res;
}
- BFS时应用 最短路径
var maxDistance = function (grid) {
let N = grid.length;
let queue = [];
// 将所有的陆地格子加入队列
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
if (grid[i][j] == 1) {
queue.push(new let[]{i, j});
}
}
}
// 如果地图上只有陆地或者海洋,返回 -1
if (queue.length==0 || queue.length == N * N) {
return -1;
}
let moves = {
{-1, 0}, {1, 0}, {0, -1}, {0, 1},
};
let distance = -1; // 记录当前遍历的层数(距离)
while (!queue.length==0) {
distance++;
let n = queue.size();
for (let i = 0; i < n; i++) {
let node = queue.pop();
let r = node[0];
let c = node[1];
for (let move of moves) {
let r2 = r + move[0];
let c2 = c + move[1];
if (inArea(grid, r2, c2) && grid[r2][c2] == 0) {
grid[r2][c2] = 2;
queue.push(new let[]{r2, c2});
}
}
}
}
return distance;
}
// 判断坐标 (r, c) 是否在网格中
var inArea = function(let grid, let r, let c) {
return 0 <= r && r < grid.length
&& 0 <= c && c < grid[0].length;
}
- dfs 二叉树的最大深度
var maxDepth = function(root){
if(root==null){
return 0;
}
let queue = [];
queue.push(root);
let ans = 0;
while(queue.length>0)[
let size = queue.length;
while(size>0){
let node = queue.pop();
if(node.left!=null){
queue.push(node.left);
}
if(node.right!=null){
queue.push(node.right);
}
size--;
}
ans++;
]
return ans;
}