Búsqueda en anchura (BFS)
Última actualización
La búsqueda en anchura explora un grafo nivel por nivel. Partiendo de un nodo origen, visita primero todos sus vecinos inmediatos, luego todos los vecinos no visitados de estos, y así sucesivamente - expandiéndose hacia afuera en anillos de distancia creciente. Pulsa reproducir arriba para verla abrirse desde el nodo inicial una capa a la vez.
BFS usa una cola de tipo primero en entrar, primero en salir, que es lo que impone el orden nivel por nivel. Como alcanza los nodos en orden de distancia en saltos, BFS encuentra el camino más corto (menos aristas) en un grafo no ponderado. Visita cada nodo y arista una vez, por lo que se ejecuta en tiempo O(V + E).
Complejidad temporal y espacial
| Medida | Complejidad | Notas |
|---|---|---|
| Tiempo | O(V + E) | Cada vértice y arista se visita una vez |
| Espacio | O(V) | Cola + conjunto de visitados, en el peor caso todos los nodos |
| Recorrido | Nivel por nivel | Los nodos más cercanos primero, en anillos |
| Camino más corto | Sí (no ponderado) | Alcanza cada nodo con menos aristas |
Paso a paso
| Paso | Qué ocurre |
|---|---|
| 1 | Encola el nodo origen. |
| 2 | Desencola el nodo del frente y márcalo como visitado. |
| 3 | Examina cada uno de sus vecinos. |
| 4 | Encola cualquier vecino que no esté ya visitado o en cola. |
| 5 | Repite hasta que la cola esté vacía. |
Ejemplo resuelto
Recorriendo este grafo desde el nodo 0, donde 0-1, 0-2, 1-3, 2-3, 2-4 son aristas:
| Paso | Visitados | Cola (frontera) |
|---|---|---|
| Inicio | {} | [0] |
Desencola 0 | {0} | [1, 2] |
Desencola 1 | {0, 1} | [2, 3] |
Desencola 2 | {0, 1, 2} | [3, 4] |
Desencola 3 | {0, 1, 2, 3} | [4] |
Desencola 4 | {0, 1, 2, 3, 4} | [] (fin) |
Cuándo usar BFS
| Úsalo cuando | Evítalo cuando |
|---|---|
| Necesitas el camino más corto en un grafo no ponderado | Las aristas tienen pesos - usa Dijkstra en su lugar |
| Es probable que el objetivo esté cerca del origen | El grafo es muy ancho - la cola puede contener una frontera enorme |
| Quieres explorar un grafo en orden por niveles | Solo necesitas alcanzar cualquier nodo, donde DFS usa menos memoria |
| Buscas componentes conexas o una ruta de mínimos saltos | Necesitas ordenamiento topológico o detección de ciclos - DFS encaja mejor |
Código de Breadth-First Search
Una implementación limpia y ejecutable de Breadth-First Search en Python, JavaScript, Java, C++, C. Elige un lenguaje, copia el código o ábrelo ya cargado en el Playground de Coddy.
Código de Breadth-First Search en Python
1from collections import deque2
3
4def bfs(graph, start):5 visited = {start}6 queue = deque([start])7 order = []8 while queue:9 node = queue.popleft()10 order.append(node)11 for neighbor in graph[node]:12 if neighbor not in visited:13 visited.add(neighbor) # mark on enqueue, not dequeue14 queue.append(neighbor)15 return order16
17
18graph = {19 "A": ["B", "C"],20 "B": ["D", "E"],21 "C": ["F"],22 "D": [],23 "E": ["F"],24 "F": [],25}26
27print("BFS order:", " -> ".join(bfs(graph, "A")))Código de Breadth-First Search en JavaScript
1const graph = {2 A: ["B", "C"],3 B: ["D", "E"],4 C: ["F"],5 D: [],6 E: ["F"],7 F: [],8};9
10function bfs(start) {11 const visited = new Set([start]);12 const queue = [start];13 const order = [];14 while (queue.length > 0) {15 const node = queue.shift(); // Dequeue the oldest node16 order.push(node);17 for (const next of graph[node]) {18 if (!visited.has(next)) {19 visited.add(next);20 queue.push(next);21 }22 }23 }24 return order;25}26
27console.log("BFS from A:", bfs("A").join(" -> "));Código de Breadth-First Search en Java
1import java.util.ArrayDeque;2import java.util.List;3import java.util.Queue;4
5public class Main {6 public static void main(String[] args) {7 List<List<Integer>> adj = List.of(8 List.of(1, 2), // neighbors of 09 List.of(0, 3, 4), // neighbors of 110 List.of(0, 5),11 List.of(1),12 List.of(1, 5),13 List.of(2, 4)14 );15 boolean[] visited = new boolean[adj.size()];16 Queue<Integer> queue = new ArrayDeque<>();17 visited[0] = true;18 queue.add(0);19
20 StringBuilder order = new StringBuilder("BFS from 0:");21 while (!queue.isEmpty()) {22 int node = queue.poll();23 order.append(" ").append(node);24 // Mark neighbors when enqueued so nothing enters twice25 for (int next : adj.get(node)) {26 if (!visited[next]) {27 visited[next] = true;28 queue.add(next);29 }30 }31 }32 System.out.println(order);33 }34}Código de Breadth-First Search en C++
1#include <iostream>2#include <queue>3#include <vector>4
5void bfs(int start, const std::vector<std::vector<int>>& adj) {6 std::vector<bool> visited(adj.size(), false);7 std::queue<int> frontier;8 visited[start] = true;9 frontier.push(start);10 // Visit nodes level by level11 while (!frontier.empty()) {12 int node = frontier.front();13 frontier.pop();14 std::cout << node << " ";15 for (int next : adj[node]) {16 if (!visited[next]) {17 visited[next] = true;18 frontier.push(next);19 }20 }21 }22}23
24int main() {25 // 6-node undirected graph as an adjacency list26 std::vector<std::vector<int>> adj = {27 {1, 2}, // 028 {0, 3, 4}, // 129 {0, 5}, // 230 {1}, // 331 {1, 5}, // 432 {2, 4}, // 533 };34 std::cout << "BFS from node 0: ";35 bfs(0, adj);36 std::cout << "\n";37 return 0;38}Código de Breadth-First Search en C
1#include <stdbool.h>2#include <stdio.h>3
4#define N 65
6void bfs(int start, const int adj[N][N]) {7 bool visited[N] = {false};8 int queue[N]; // fixed-size queue: head chases tail9 int head = 0, tail = 0;10 visited[start] = true;11 queue[tail++] = start;12 // Visit nodes level by level13 while (head < tail) {14 int node = queue[head++];15 printf("%d ", node);16 for (int next = 0; next < N; next++) {17 if (adj[node][next] && !visited[next]) {18 visited[next] = true;19 queue[tail++] = next;20 }21 }22 }23}24
25int main(void) {26 // 6-node undirected graph as an adjacency matrix27 int adj[N][N] = {28 {0, 1, 1, 0, 0, 0},29 {1, 0, 0, 1, 1, 0},30 {1, 0, 0, 0, 0, 1},31 {0, 1, 0, 0, 0, 0},32 {0, 1, 0, 0, 0, 1},33 {0, 0, 1, 0, 1, 0},34 };35 printf("BFS from node 0: ");36 bfs(0, adj);37 printf("\n");38 return 0;39}Preguntas frecuentes sobre la búsqueda en anchura
¿Cuál es la complejidad temporal de BFS?
O(V + E), donde V es el número de vértices y E el de aristas, ya que visita cada vértice una vez y examina cada arista una vez. Usa O(V) de espacio para la cola y el conjunto de visitados.¿Encuentra BFS el camino más corto?
¿Cuál es la diferencia entre BFS y DFS?
¿Cuándo debo usar BFS en lugar del algoritmo de Dijkstra?
O(V + E) sin una cola de prioridad. El algoritmo de Dijkstra es necesario cuando las aristas tienen pesos distintos; ejecutar BFS puro en un grafo ponderado da el camino de menos saltos, no el de menor costo.