图由顶点和边构成,图包括无向图和有向图。
连通图:任意两个顶点都有路径相连。
其中无向图如果连通,最少需要n-1条边;有向图强连通,最少需要n条边。
一、深度优先搜索(DFS)
function dfs(graph, start) {
const visited = new Set();
function explore(node) {
if (visited.has(node)) return;
console.log(node); // 访问节点
visited.add(node);
for (const neighbor of graph[node]) {
explore(neighbor);
}
}
explore(start);
}
// 示例图表示为邻接表
const graph = {
A: ['B', 'C'],
B: ['A', 'D', 'E'],
C: ['A', 'F'],
D: ['B'],
E: ['B', 'F'],
F: ['C', 'E']
};
dfs(graph, 'A');
二、广度优先搜索(BFS)
function bfs(graph, start) {
const visited = new Set();
const queue = [start];
while (queue.length > 0) {
const node = queue.shift();
if (visited.has(node)) continue;
console.log(node); // 访问节点
visited.add(node);
for (const neighbor of graph[node]) {
if (!visited.has(neighbor)) {
queue.push(neighbor);
}
}
}
}
// 示例图表示为邻接表
const graph = {
A: ['B', 'C'],
B: ['A', 'D', 'E'],
C: ['A', 'F'],
D: ['B'],
E: ['B', 'F'],
F: ['C', 'E']
};
bfs(graph, 'A');
- DFS:使用递归函数
explore
来访问节点,使用 Set 来记录已访问的节点。 - BFS:使用队列来逐层访问节点,同样使用 Set 来记录已访问的节点。
三、区别
广度优先搜索(BFS)
- 遍历顺序:BFS从起始节点开始,首先访问所有相邻节点,然后逐层向外扩展。
- 数据结构:使用队列(FIFO)实现。
- 应用场景:适用于寻找最短路径(无权图),如在迷宫中找到最短路径。
- 特点:逐层访问,先访问近的节点。
深度优先搜索(DFS)
- 遍历顺序:DFS从起始节点开始,沿着一个分支一直深入到不能再深入为止,然后回溯并探索其他分支。
- 数据结构:使用栈(LIFO)实现,通常通过递归实现。
- 应用场景:适用于路径查找、连通性检测、拓扑排序等。
- 特点:深入访问,先访问远的节点。