0Pricing
DSA Interview Prep · Leçon

Tri topologique par DFS en post-ordre

Exécutez DFS et empilez chaque nœud une fois ses voisins entièrement explorés, puis dépilez la pile pour obtenir un ordre topologique valide.

Tri topologique par DFS en post-ordre est une leçon DSA Interview Prep gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage DSA Interview Prep, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours DSA Interview Prep comprend 4 leçons au total.

Idée du tri topologique fondé sur DFS

Le deuxième algorithme classique de tri topologique utilise DFS avec un traitement en postordre. Après avoir exploré complètement tous les voisins d’un sommet, ainsi que leurs descendants, empilez le sommet. Une fois tous les sommets traités, utilisez pop sur la pile pour lire l’ordre topologique. Un sommet empilé après toutes ses dépendances signifie qu’il vient en premier dans l’ordre — le postordre inversé constitue donc le tri topologique.

Intuition du postordre

Considérez un graphe de dépendances où le cours A nécessite le cours B. Lorsque DFS visite A, il commence par appeler récursivement B. B n’a aucun prérequis, il est donc terminé en premier et empilé en premier. A est ensuite terminé et empilé. Dépiler la pile donne A avant B dans la sortie — mais on inverse le résultat à la fin, ce qui donne B avant A : prendre B d’abord, puis A. Le postordre empile les dépendances avant les éléments qui en dépendent ; la pile inversée est donc un ordre topologique valide.

DFS à trois couleurs pour détecter les cycles

Utilisez trois états pour les sommets visités : WHITE (0) = non visité, GREY (1) = en cours de traitement, dans la pile d’appels de DFS, BLACK (2) = entièrement traité. Une arête arrière — une arête vers un sommet GREY — indique un cycle. Les arêtes vers des sommets BLACK sont sûres, car ceux-ci ont déjà été entièrement explorés. Ce schéma à trois couleurs détecte correctement tous les cycles dans les graphes orientés.

WHITE, GREY, BLACK = 0, 1, 2
color = [WHITE] * n  # n = number of nodes

# During DFS:
# color[node] = GREY   (entering node)
# recurse into neighbours
# if neighbour is GREY: cycle found!
# color[node] = BLACK  (leaving node, push to stack)

Implémentation complète du tri topologique avec DFS

Utilisez un DFS récursif qui colore les sommets, les empile en postordre et renvoie Faux en cas de détection d’un cycle. Après avoir visité tous les sommets, la pile inversée donne l’ordre topologique.

from collections import defaultdict

def dfs_topological_sort(n, edges):
    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
    
    WHITE, GREY, BLACK = 0, 1, 2
    color = [WHITE] * n
    stack = []
    
    def dfs(node):
        color[node] = GREY
        for nxt in graph[node]:
            if color[nxt] == GREY:
                return False  # cycle
            if color[nxt] == WHITE:
                if not dfs(nxt):
                    return False
        color[node] = BLACK
        stack.append(node)
        return True
    
    for i in range(n):
        if color[i] == WHITE:
            if not dfs(i):
                return []  # cycle
    
    return stack[::-1]

print(dfs_topological_sort(4, [(0,1),(0,2),(1,3),(2,3)]))

DFS itératif pour éviter le dépassement de pile

La limite de récursivité de Python, fixée par défaut à 1000, pose problème pour les grands graphes. Un DFS itératif utilisant une pile explicite permet de l’éviter. L’astuce consiste à empiler d’abord (node, False) ; lorsqu’il est dépilé avec False, empilez (node, True), ce qui signifie « je reviendrai ici après l’exploration », puis empilez tous les voisins non visités avec Faux. Lorsqu’il est dépilé avec True, colorez-le en BLACK et empilez-le dans la pile de résultats.

from collections import defaultdict

def dfs_topo_iterative(n, edges):
    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
    
    WHITE, GREY, BLACK = 0, 1, 2
    color = [WHITE] * n
    result = []
    
    for start in range(n):
        if color[start] != WHITE:
            continue
        stack = [(start, False)]
        while stack:
            node, returning = stack.pop()
            if returning:
                color[node] = BLACK
                result.append(node)
            elif color[node] == WHITE:
                color[node] = GREY
                stack.append((node, True))  # will return here
                for nxt in graph[node]:
                    if color[nxt] == WHITE:
                        stack.append((nxt, False))
    
    return result[::-1]

Comparaison entre DFS et l’algorithme de Kahn

Les deux s’exécutent en O(V + E). Principales différences : l’algorithme de Kahn (BFS) produit naturellement les sommets dans l’ordre des dépendances les plus en amont et offre une détection des cycles plus simple, fondée sur une vérification de longueur. Le postordre de DFS fonctionne de manière récursive et détecte explicitement les arêtes arrière. L’algorithme de Kahn est préférable lorsque vous voulez obtenir le résultat dans l’ordre direct, sans inversion. DFS est préférable lorsque vous avez besoin du postordre complet à d’autres fins, comme la détection des SCC. Les deux conviennent aux entretiens.

Postordre sur un arbre et un DAG

Dans un arbre, le postordre parcourt le sous-arbre gauche → le sous-arbre droit → la racine. Dans un DAG, le DFS en postordre visite toutes les dépendances d’un sommet avant de traiter le sommet lui-même — c’est la même idée généralisée à plusieurs prédécesseurs et à une structure de graphe arbitraire. La racine d’un arbre DFS, c’est-à-dire le sommet de départ, est empilée après tous ses descendants, ce qui la fait apparaître en premier dans la pile inversée — la position topologique correcte pour un sommet sans prédécesseurs.

Dictionnaire extraterrestre (LeetCode 269)

Dictionnaire extraterrestre : étant donné une liste triée de mots dans une langue extraterrestre, déduisez l’ordre des caractères. Comparez les mots adjacents caractère par caractère pour trouver la première différence — cela donne une arête c1 → c2, ce qui signifie que le premier caractère précède le second. Recueillez toutes ces arêtes et exécutez un tri topologique pour produire l’ordre des caractères extraterrestres. Si un cycle existe, l’ordre est invalide.

from collections import defaultdict

def alienOrder(words):
    graph = defaultdict(set)
    all_chars = set(c for w in words for c in w)
    
    for i in range(len(words)-1):
        w1, w2 = words[i], words[i+1]
        if len(w1) > len(w2) and w1.startswith(w2):
            return ''  # invalid (prefix comes after)
        for c1, c2 in zip(w1, w2):
            if c1 != c2:
                graph[c1].add(c2)
                break
    
    # DFS topological sort on character graph
    WHITE, GREY, BLACK = 0, 1, 2
    color = {c: WHITE for c in all_chars}
    result = []
    
    def dfs(c):
        color[c] = GREY
        for nxt in graph[c]:
            if color[nxt] == GREY: return False
            if color[nxt] == WHITE and not dfs(nxt): return False
        color[c] = BLACK
        result.append(c)
        return True
    
    for c in all_chars:
        if color[c] == WHITE:
            if not dfs(c): return ''
    return ''.join(result[::-1])

print(alienOrder(['wrt','wrf','er','ett','rftt']))  # 'wertf'

Tri topologique avec contraintes

Certains problèmes demandent un tri topologique respectant des contraintes supplémentaires, comme le maintien de l’ordre relatif des éléments de la liste d’origine. Combinez l’algorithme de Kahn avec une file de priorité personnalisée ou un pré-tri : conservez l’ordre relatif d’origine des éléments en effectuant un tri stable du contenu de la file d’attente à chaque étape. Ces variantes sous contrainte évaluent une compréhension plus approfondie de la souplesse de l’algorithme.

Reconnaître les problèmes de tri topologique

Voici des expressions indicatrices dans les problèmes d’entretien qui signalent un tri topologique : « dépendances fournies », « prérequis », « ordre des tâches », « ordre de construction », « toutes les tâches peuvent-elles être terminées ? », « trouver une séquence valide ». Si le problème implique un ordre entre des éléments dont certains doivent précéder les autres, construisez un graphe orienté et appliquez le tri topologique de Kahn ou de DFS. La détection des cycles constitue souvent une exigence secondaire du même problème.

Comparaison des sorties de DFS et de Kahn

DFS et l’algorithme de Kahn peuvent produire des ordres topologiques valides différents pour un même graphe. Les deux sont corrects : un DAG peut posséder plusieurs ordres topologiques valides. Pour vérifier la validité, assurez-vous que, pour chaque arc u → v du graphe, le sommet de départ apparaît avant le sommet d’arrivée dans l’ordre de sortie. Pour les problèmes d’entretien qui exigent un ordre précis, par exemple l’ordre lexicographiquement le plus petit, utilisez Kahn avec un tas min : le postordre de DFS ne produit pas naturellement l’ordre lexicographiquement minimal.

Vérification rapide

Testez votre compréhension des concepts de Structures de données et algorithmes & Préparation aux entretiens de programmation présentés dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris que le tri topologique en postordre de DFS empile les sommets après l’exploration de toutes leurs dépendances, que le marquage à trois couleurs (WHITE/GREY/BLACK) détecte les cycles via les arêtes arrière vers les sommets GREY et que l’inversion de la pile de postordre produit un ordre topologique valide. Nous allons ensuite appliquer directement le tri topologique aux problèmes Planification des cours I et II.

Questions Fréquemment Posées

La leçon « Tri topologique par DFS en post-ordre » est-elle gratuite ?

Oui — le texte complet de « Tri topologique par DFS en post-ordre » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours DSA Interview Prep, passe à CoddyKit PRO. Le cours DSA Interview Prep comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Tri topologique par DFS en post-ordre » ?

Exécutez DFS et empilez chaque nœud une fois ses voisins entièrement explorés, puis dépilez la pile pour obtenir un ordre topologique valide. Tu pratiques DSA Interview Prep avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer DSA Interview Prep ?

Aucune expérience préalable n'est requise. DSA Interview Prep sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Tri topologique par DFS en post-ordre » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon DSA Interview Prep ?

Oui. Chaque leçon DSA Interview Prep inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Algorithme de Kahn : tri topologique par BFS
  2. Tri topologique par DFS en post-ordre
  3. Planification de cours I et II
  4. Composantes fortement connexes avec Kosaraju
← Retour à DSA Interview Prep