Menu
Coddy logo textTech

Búsqueda en profundidad (DFS)

Última actualización

La búsqueda en profundidad explora un grafo yendo lo más profundo posible por cada rama antes de retroceder. Partiendo de un nodo origen, visita un vecino, luego el vecino de ese vecino, y así sucesivamente hasta llegar a un callejón sin salida (un nodo sin vecinos no visitados), momento en el que retrocede y prueba la siguiente rama. Pulsa reproducir arriba para verla descender por un camino, llegar al fondo y volver a salir.

DFS se expresa de forma natural con una pila: ya sea una pila explícita (como se anima aquí) o la pila de llamadas mediante recursión. Visita cada nodo y arista una vez, por lo que se ejecuta en tiempo O(V + E) para un grafo con V vértices y E aristas.

Complejidad temporal y espacial

MedidaComplejidadNotas
TiempoO(V + E)Cada vértice y arista se visita una vez
EspacioO(V)Pila + conjunto de visitados, en el peor caso todos los nodos
RecorridoLo más profundo primeroSigue una rama hasta el final antes que las demás
Estructura de datosPila (o recursión)El orden LIFO impulsa el comportamiento en profundidad

Paso a paso

PasoQué ocurre
1Apila el nodo origen en la pila.
2Extrae un nodo; si ya está visitado, sáltalo.
3Márcalo como visitado y registra la arista que lo alcanzó.
4Apila todos sus vecinos no visitados.
5Repite hasta que la pila esté vacía.

Ejemplo resuelto

DFS iterativo desde A en el grafo A → [B, C], B → [D], C → [E], apilando los vecinos en el orden indicado (la pila LIFO extrae primero el último apilado):

PasoPila (cima a la derecha)VisitadosAcción
1[A]{}Apila el origen A.
2[B, C]{A}Extrae A, márcalo visitado, apila los vecinos B y luego C.
3[B, E]{A, C}Extrae C, márcalo visitado, apila el vecino E.
4[B]{A, C, E}Extrae E, márcalo visitado, sin vecinos.
5[D]{A, C, E, B}Extrae B, márcalo visitado, apila el vecino D.
6[]{A, C, E, B, D}Extrae D, márcalo visitado, pila vacía: terminado.

Cuándo usar DFS

Úsalo cuandoEvítalo cuando
Necesitas detección de ciclos, orden topológico o encontrar componentes conexas.Necesitas el camino más corto en un grafo no ponderado: eso lo hace BFS, no DFS.
El grafo es ancho y poco profundo, por lo que una pila usa mucha menos memoria que una cola con muchos nodos de frontera.El grafo es muy profundo y usas recursión: la pila de llamadas puede desbordarse.
Quieres explorar caminos de forma exhaustiva, como al resolver laberintos o en búsqueda con backtracking.Necesitas descubrir los nodos por orden de distancia desde el origen.
Compruebas la alcanzabilidad o si existe un camino entre dos nodos.Debes garantizar el mínimo número de aristas en el camino encontrado.

Una implementación limpia y ejecutable de Depth-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 Depth-First Search en Python

Python
1def dfs(graph, node, visited):2    visited.add(node)3    order = [node]4    for neighbor in graph[node]:5        if neighbor not in visited:6            order.extend(dfs(graph, neighbor, visited))7    return order8
9
10graph = {11    "A": ["B", "C"],12    "B": ["D", "E"],13    "C": ["F"],14    "D": [],15    "E": ["F"],16    "F": [],17}18
19order = dfs(graph, "A", set())20print("DFS order:", " -> ".join(order))
Ejecuta este código en el Playground de Python

Preguntas frecuentes sobre la búsqueda en profundidad

¿Cuál es la complejidad temporal de DFS?
DFS se ejecuta en tiempo O(V + E), donde V es el número de vértices y E el de aristas, porque visita cada vértice una vez y examina cada arista una vez. Usa espacio O(V) para la pila y el conjunto de visitados.
¿Cuál es la diferencia entre DFS y BFS?
DFS usa una pila y profundiza por una rama antes de retroceder, mientras que BFS usa una cola y explora nivel por nivel, primero los nodos más cercanos. BFS encuentra el camino más corto en un grafo no ponderado; DFS no, pero usa menos memoria en grafos anchos y es natural para tareas como la detección de ciclos y el orden topológico.
¿DFS es recursivo o iterativo?
Ambos funcionan. La versión recursiva usa implícitamente la pila de llamadas del programa y es muy concisa; la versión iterativa usa una pila explícita (como la animación de aquí) y evita desbordamientos de pila por recursión profunda en grafos grandes.
¿Cuándo debería usar DFS en lugar de BFS?
Usa DFS cuando necesites explorar caminos completos: detección de ciclos, orden topológico, componentes conexas o búsqueda con backtracking como resolver un laberinto. También usa menos memoria en grafos anchos, ya que la pila solo contiene la frontera de una rama a la vez. Recurre a BFS cuando necesites el camino más corto en un grafo no ponderado o los nodos en orden de distancia desde el origen.
¿Puede DFS encontrar el camino más corto?
No de forma fiable. DFS devuelve el primer camino que encuentra, que a menudo no es el de menos aristas, porque se compromete a profundizar en lugar de expandirse de forma uniforme. Para caminos más cortos en un grafo no ponderado usa BFS, y para grafos ponderados usa el algoritmo de Dijkstra.
¿Por qué DFS necesita un conjunto de visitados?
Sin un conjunto de visitados, DFS volverá a visitar nodos alcanzables por varios caminos y, en un grafo cíclico, entrará en un bucle infinito. Marcar un nodo como visitado al extraerlo (y saltar las extracciones ya visitadas) garantiza que cada nodo se procese una vez y mantiene el tiempo de ejecución en O(V + E). Un error común es marcar los nodos como visitados solo al extraerlos mientras se siguen apilando duplicados, lo cual es correcto pero puede dejar entradas obsoletas en la pila que hay que saltar.
Coddy programming languages illustration

Domina los algoritmos con Coddy

COMENZAR