Menu
Coddy logo textTech

Ordenamiento Topológico

Última actualización

Un ordenamiento topológico de un grafo acíclico dirigido (DAG) es un orden lineal de sus nodos tal que para cada arista u → v, u aparece antes que v. Responde preguntas como «¿en qué orden puedo ejecutar estas tareas para que cada prerrequisito termine primero?». Pulsa reproducir arriba para ver cómo el algoritmo de Kahn extrae los nodos en un orden válido.

El algoritmo de Kahn toma repetidamente un nodo sin aristas entrantes restantes (grado de entrada 0), lo añade al orden y elimina sus aristas salientes, lo que puede liberar nuevos nodos con grado de entrada 0. Solo funciona sobre un DAG: si existe un ciclo, algunos nodos nunca llegan a grado de entrada 0 y no existe un orden válido. Se ejecuta en tiempo O(V + E).

Complejidad temporal y espacial

MedidaComplejidadNotas
TiempoO(V + E)Cada nodo se emite una vez, cada arista se elimina una vez
EspacioO(V)Conteos de grado de entrada + conjunto listo + orden
RequiereUn DAGLos ciclos no tienen ordenamiento topológico
ResultadoNo únicoPueden existir muchos órdenes válidos

Paso a paso (algoritmo de Kahn)

PasoQué ocurre
1Calcular el grado de entrada (número de aristas entrantes) de cada nodo.
2Reunir todos los nodos con grado de entrada 0 en un conjunto listo.
3Tomar un nodo listo y añadirlo al orden de salida.
4Decrementar el grado de entrada de cada uno de sus sucesores.
5Todo sucesor que llegue a grado de entrada 0 se une al conjunto listo.
6Repetir hasta que el conjunto listo esté vacío.

Ejemplo resuelto

Ordenando el DAG con aristas A→C, B→C, C→D, C→E, D→F, E→F (grados de entrada iniciales A:0 B:0 C:2 D:1 E:1 F:2):

PasoConjunto listoOrdenAcción
0{A, B}[]A y B empiezan con grado de entrada 0, así que ambos están listos.
1{B}[A]Emitir A; su arista A→C baja el grado de entrada de C de 2 → 1.
2{C}[A, B]Emitir B; su arista B→C baja C de 1 → 0, así que C queda listo.
3{D, E}[A, B, C]Emitir C; las aristas C→D y C→E bajan D y E a 0, ambos quedan listos.
4{E}[A, B, C, D]Emitir D; su arista D→F baja el grado de entrada de F de 2 → 1.
5{F}[A, B, C, D, E]Emitir E; su arista E→F baja F de 1 → 0, así que F queda listo.
6{}[A, B, C, D, E, F]Emitir F; el conjunto listo está vacío y los 6 nodos están ordenados: listo.

Cuándo usar el ordenamiento topológico

Úsalo cuandoEvítalo cuando
Necesitas un orden que respete dependencias (pasos de compilación, instalación de paquetes, prerrequisitos de cursos).El grafo no es dirigido: el orden topológico solo se define para grafos dirigidos.
El grafo es un DAG y quieres cualquier orden lineal válido.El grafo puede contener ciclos y aun así necesitas un orden total (no existe ninguno).
Quieres detectar ciclos de forma barata: un ordenamiento topológico fallido demuestra que existe uno.Necesitas el orden más corto u óptimo según algún peso; el ordenamiento topológico simple ignora los pesos.
Procesarás el orden una sola vez en O(V + E).Las aristas cambian constantemente y debes reordenar en cada actualización, donde encaja mejor una estructura incremental.

Código de Topological Sort

Una implementación limpia y ejecutable de Topological Sort 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 Topological Sort en Python

Python
1from collections import deque2
3
4def topological_sort(graph):5    # Kahn's algorithm: repeatedly remove nodes with no incoming edges6    in_degree = {node: 0 for node in graph}7    for node in graph:8        for neighbor in graph[node]:9            in_degree[neighbor] += 110    queue = deque(node for node in graph if in_degree[node] == 0)11    order = []12    while queue:13        node = queue.popleft()14        order.append(node)15        for neighbor in graph[node]:16            in_degree[neighbor] -= 117            if in_degree[neighbor] == 0:18                queue.append(neighbor)19    if len(order) != len(graph):20        raise ValueError("Graph has a cycle, no topological order")21    return order22
23
24graph = {25    "shirt": ["tie", "jacket"],26    "tie": ["jacket"],27    "pants": ["shoes", "jacket"],28    "socks": ["shoes"],29    "shoes": [],30    "jacket": [],31}32
33print(" -> ".join(topological_sort(graph)))
Ejecuta este código en el Playground de Python

Preguntas frecuentes sobre el ordenamiento topológico

¿Para qué sirve un ordenamiento topológico?
Ordena las tareas de modo que cada dependencia venga antes de lo que la necesita. Usos reales incluyen sistemas de compilación y gestores de paquetes (compilar dependencias primero), la planificación de cursos con prerrequisitos y el orden de evaluación de fórmulas en hojas de cálculo.
¿Cuál es la complejidad temporal del ordenamiento topológico?
Tanto el algoritmo de Kahn como el enfoque basado en DFS se ejecutan en tiempo O(V + E), ya que cada nodo se procesa una vez y cada arista se examina una vez. Usan O(V) de espacio adicional.
¿Por qué el ordenamiento topológico requiere un DAG?
Un ciclo dirigido crea una contradicción: si a debe venir antes de b y b debe venir antes de a, ningún orden lineal satisface ambas condiciones. Por eso existe un ordenamiento topológico si y solo si el grafo es un grafo acíclico dirigido. El algoritmo de Kahn detecta un ciclo cuando termina antes de emitir todos los nodos.
¿Cuál es la diferencia entre el algoritmo de Kahn y el ordenamiento topológico por DFS?
El algoritmo de Kahn es iterativo y parecido a BFS: elimina repetidamente los nodos con grado de entrada 0, lo que hace explícitas la detección de ciclos y la ordenación. El enfoque DFS visita los nodos recursivamente y antepone cada uno al orden cuando su recursión termina, produciendo el inverso de los tiempos de finalización. Ambos son O(V + E); el de Kahn evita la recursión profunda y expone el conjunto listo de forma natural, mientras que el DFS suele ser más corto de escribir.
¿Cuándo debo usar el ordenamiento topológico en lugar de un ordenamiento normal?
Usa el ordenamiento topológico cuando el orden esté definido por dependencias entre elementos en lugar de por una clave comparable. Un ordenamiento por comparación como el mergesort O(n log n) ordena por valor; el ordenamiento topológico ordena por aristas de «debe venir antes» y, a diferencia de un ordenamiento por comparación, puede producir muchas respuestas válidas para la misma entrada.
¿Es único el resultado de un ordenamiento topológico?
Normalmente no. Siempre que dos o más nodos estén listos (grado de entrada 0) al mismo tiempo, puedes emitirlos en cualquier orden, por lo que la mayoría de los DAG admiten varios ordenamientos topológicos válidos. El orden es único solo cuando hay exactamente un nodo listo en cada paso, lo que ocurre cuando el DAG forma una única cadena (un camino hamiltoniano).
Coddy programming languages illustration

Domina los algoritmos con Coddy

COMENZAR