数据结构与算法之Leetcode-深度遍历与广度遍历(DFS&BFS)

77 篇文章 0 订阅
36 篇文章 0 订阅
本文探讨了深度优先搜索(DFS)和广度优先搜索(BFS)在遍历树和图时的差异。虽然DFS通常更便捷,但BFS在层序遍历和寻找最短路径方面具有优势。层序遍历能按层次顺序访问二叉树节点,而最短路径问题如网格中陆地距离计算则需要BFS。DFS和BFS各有其适用场景,选择哪种取决于具体需求。
摘要由CSDN通过智能技术生成

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;
}
参考链接

nette
bfs-二叉树的最大深度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值