《JavaScript算法》深度优先&广度优先

139 阅读2分钟

深度优先搜索(DFS)和广度优先搜索(BFS)是图和树的两种常见遍历策略。下面为您提供了JavaScript中的DFS和BFS实现的代码及其详细注释。

1.深度优先搜索 (DFS)

递归版(常用于树的遍历):

function dfs(node) {
    if (node === null) return;     // 基础的结束条件,例如对于空节点

    console.log(node.value);      // 访问当前节点

    // 递归调用子节点
    for (let child of node.children) {
        dfs(child);
    }
}

非递归版(使用栈,常用于图的遍历):

function dfs(node) {
    let stack = [node];            // 使用一个栈来存储待遍历的节点

    while (stack.length > 0) {
        let current = stack.pop();   // 弹出当前节点
        console.log(current.value);  // 访问当前节点

        // 将子节点入栈
        // 为了保证和递归版相同的访问顺序,我们需要从后往前将子节点推入栈  
        for (let i = current.children.length - 1; i >= 0; i--) {  
            stack.push(current.children[i]);  
        } 
    }
}

2. 广度优先搜索 (BFS)

非递归版(使用队列):

function bfs(node) {
    let queue = [node];           // 使用一个队列来存储待遍历的节点

    while (queue.length > 0) {
        let current = queue.shift();   // 从队列前端取出当前节点
        console.log(current.value);    // 访问当前节点

        // 将子节点入队
        for (let child of current.children) {
            queue.push(child);
        }
    }
}

常见题型

  1. 树或图的遍历:输出树或图的所有节点。
  2. 路径查找:例如,寻找两个节点之间的最短路径(通常使用BFS)。
  3. 判断是否存在循环:在图中查找循环或环(可以使用DFS或BFS)。
  4. 最大连通分量:找出图中最大的连通分量。
  5. 拓扑排序:对一个有向无环图进行排序,使得对于每条有向边 U -> V,U 都在 V 之前(通常使用DFS)。
  6. 岛屿数量:给定一个二维地图,计算岛屿的数量。
  7. 区域填充:如“填色”工具。

这只是DFS和BFS的一些基本应用。在实际问题中,您可能还需要结合其他数据结构和技巧来求解。