Terminale · Algorithmique

Parcourir un graphe en profondeur : DFS

Dans un labyrinthe, on peut suivre un couloir aussi loin que possible, puis revenir au dernier embranchement non exploré. Le parcours en profondeur organise cette stratégie. Contrairement à un arbre, un graphe peut ramener vers un sommet déjà rencontré : il faut conserver une mémoire des découvertes.

SofienAvec SofienIngénieur et enseignant en informatique
Dans ce chapitre

Un cap pour ce chapitre

Ce que vous saurez faire

  • Tracer un parcours en profondeur déterministe.
  • Utiliser un ensemble de sommets visités.
  • Distinguer accessibilité et plus court chemin.
Les bases utiles pour commencer

Fixer l’ordre des voisins

Considérons le graphe non orienté avec les liaisons A-B, A-C, B-D, B-E et C-E. Le sommet F est isolé. Nous traiterons les voisins dans l’ordre alphabétique. Sans cet ordre, plusieurs parcours en profondeur peuvent être corrects ; une séquence ne doit pas être déclarée fausse simplement parce qu’elle suit un autre choix autorisé.

En partant de A, on découvre B, puis D. D ne possède pas de voisin inconnu, donc on revient à B. On découvre ensuite E, puis C. Depuis C, tous les voisins sont déjà découverts. La séquence de première découverte est A,B,D,E,C.

Marquer avant d’explorer davantage

Un sommet doit être marqué comme visité dès sa découverte. Lorsque ses voisins sont examinés, les sommets déjà visités sont ignorés pour les nouveaux appels. Cela empêche de tourner entre deux voisins d’un graphe non orienté ou de parcourir indéfiniment un cycle.

def profondeur(graphe, sommet, visites):
    visites.add(sommet)
    for voisin in graphe[sommet]:
        if voisin not in visites:
            profondeur(graphe, voisin, visites)

L’ensemble visites est partagé volontairement entre les appels : il représente les découvertes de tout le parcours. En créer un nouveau vide à chaque appel ferait perdre cette mémoire globale et pourrait réintroduire des visites infinies.

Le test doit avoir lieu avant l’appel récursif, et le marquage avant la visite des voisins. Pour chaque sommet découvert, une seule exploration de son voisinage sera donc engagée. Sur une arête non orientée, l’autre extrémité retrouvera le parent dans ses voisins, mais reconnaîtra son marquage.

Comprendre les retours et la pile

La récursion conserve implicitement les sommets dont certains voisins restent à examiner. Une version itérative peut utiliser une pile explicite. Pour reproduire exactement l’ordre d’une version récursive, il faut préciser quand les sommets sont marqués et dans quel ordre les voisins sont empilés : une pile inverse l’ordre de retrait.

Il existe donc plusieurs variantes correctes de DFS. Une trace doit correspondre à l’algorithme réellement donné. Le retour à un sommet ne signifie pas qu’il est découvert une deuxième fois ; il permet de poursuivre l’exploration de ses voisins encore inconnus.

Ce que le parcours permet de conclure

Depuis A, le parcours atteint les sommets accessibles par des liaisons, mais pas F, qui est isolé. Pour visiter tout un graphe éventuellement non connexe, on relance le parcours depuis chaque sommet encore inconnu. On obtient alors une forêt de parcours.

DFS peut servir à rechercher un chemin, explorer une composante ou contribuer à détecter des cycles. Le premier chemin trouvé n’est pas nécessairement celui qui utilise le moins d’arêtes. Avec des listes d’adjacence, chaque sommet et chaque liaison sont examinés un nombre borné de fois ; le travail est de l’ordre du nombre de sommets plus celui des arêtes.

Exemple suivi : découvrir puis revenir

Reprenons le départ A. Les premières piles actives sont [A], [A,B], [A,B,D]. Après traitement de D, la pile redevient [A,B] et B reprend au voisin suivant, E. On obtient [A,B,E], puis [A,B,E,C]. C voit A et E déjà marqués et ne crée aucun appel supplémentaire. Les retours retirent ensuite C, E, B puis A. La liste des découvertes reste A,B,D,E,C.

Cette trace distingue trois informations : l’ensemble des sommets déjà rencontrés, l’ordre de leur première découverte et la pile des appels non terminés. D reste visité après avoir disparu de la pile. E est accessible depuis A par A-B-E, mais l’ordre des découvertes A,B,D,E n’est pas lui-même un chemin : D et E ne sont pas reliés directement. Pour donner un chemin, il faut conserver les parents de découverte ou vérifier chaque liaison.

Exemple suivi : explorer une autre composante

Le sommet F n’a aucun voisin. Un appel depuis F le marque, constate son voisinage vide et revient. Il découvre exactement un sommet ; il ne conclut rien sur les chemins entre A, B, C, D et E. Pour parcourir tout le graphe, une boucle extérieure examine les sommets et lance DFS seulement pour ceux qui ne sont pas encore marqués. Depuis A puis F, elle produit deux arbres de parcours, correspondant ici aux deux composantes connexes.

Dans un graphe orienté, on suit uniquement les successeurs : le résultat décrit les sommets accessibles dans ce sens. Pour comparer deux traces, annoncez également la stratégie d’empilement d’une version itérative. Empiler A puis B fait retirer B avant A ; une simple inversion des voisins peut changer l’ordre observé. Les garanties essentielles restent l’exploration des sommets accessibles et l’absence de redécouvertes, sous réserve d’un ensemble partagé et d’une représentation fidèle du graphe.

À vous de faire varier les choses

Explorez les branches et les retours

Choisissez un départ puis avancez dans les événements. Le graphe surligne le sommet traité ; la table indique la pile récursive.

Lire le résultat de l’expérience initiale

Découverte de A.

Pile des appels : A. Les voisins sont examinés alphabétiquement.

ÉvénementSommetPile après événement
DécouverteAA

La pile explique les retours ; l’ensemble des visites explique pourquoi certains voisins sont ignorés.

De la compréhension à l’autonomie

À vous de résoudre

Cherchez d’abord par vous-même. Vérifiez les résultats demandés, utilisez les indices si nécessaire, puis comparez votre méthode à la correction.

Exercice 1 · Appliquer#

Suivre l’ordre annoncé

Dans le graphe du cours, partez de A et examinez les voisins alphabétiquement. Donnez les trois premiers sommets découverts.

Indice 1

A choisit B avant C.

Indice 2

B choisit D avant E après avoir ignoré A.

Comprendre la correction

Les trois premiers sont A,B,D. Le parcours poursuit une branche avant de revenir. C attend encore, même s’il est directement voisin de A, car DFS privilégie l’approfondissement depuis B.

Exercice 2 · Comprendre#

Comprendre un retour

Après la découverte de D, pourquoi le parcours revient-il à B sans ajouter un nouveau sommet ?

Indice 1

Quels voisins possède D ?

Indice 2

Le seul voisin est-il déjà découvert ?

Comprendre la correction

D n’a que B pour voisin, et B est déjà visité. L’appel consacré à D se termine ; l’appel de B reprend l’examen de ses voisins. Ce retour ne constitue pas une nouvelle découverte de B.

Exercice 3 · Corriger#

Réparer une mémoire locale

Chaque appel recrée visites=set() avant d’explorer ses voisins dans un graphe A-B. Pourquoi cela peut-il boucler ?

Indice 1

L’appel de B se souvient-il qu’A a été visité ?

Indice 2

Les deux appels peuvent se rappeler alternativement.

Comprendre la correction

La mémoire est perdue à chaque appel. B considère A comme nouveau, puis A considère B comme nouveau, et ainsi de suite. Il faut partager un même ensemble des découvertes pour tout le parcours, en marquant chaque sommet avant ses appels descendants.

Exercice 4 · Justifier#

Distinguer chemin et distance

Le parcours découvre E via A-B-E, puis C via E. A-C existe directement. Le chemin de découverte vers C est-il minimal ?

Indice 1

Comparez A-B-E-C et A-C.

Indice 2

DFS cherche d’abord à approfondir une branche.

Comprendre la correction

Non. Le chemin de découverte comporte trois arêtes, alors qu’A-C en comporte une. DFS fournit un chemin possible et une exploration, mais ne garantit pas le minimum de sauts. Un parcours en largeur convient à cette distance dans un graphe non pondéré.

Exercice 5 · Problème de synthèse#

Problème : une liste de visites n’est pas un chemin

Dans le graphe du cours, DFS découvre A,B,D,E,C. Vérifiez si cette liste constitue un chemin. Donnez la pile lors de la découverte de C, puis un véritable chemin de A à C issu des parents de découverte. Comparez-le à la liaison directe A-C.

Indice 1

D n’est relié qu’à B.

Indice 2

La pile indique le chemin récursif actuellement actif.

Comprendre la correction

La liste n’est pas un chemin puisque D-E n’existe pas. Lors de la découverte de C, la pile est A,B,E,C et fournit un chemin de trois arêtes. A-C est pourtant une liaison directe d’une arête. DFS explore profondément avant de comparer les longueurs : la liste de visite, la pile et le plus court chemin représentent trois objets différents.

Exercice 6 · Problème de synthèse#

Problème : changer le point de départ

Partez de D dans le même graphe, voisins alphabétiques. Donnez l’ordre complet de découverte et les parents de A, C et E. Combien de lancements depuis des sommets non visités faut-il pour couvrir aussi F ?

Indice 1

D conduit d’abord à B, qui choisit A avant E.

Indice 2

F est une composante distincte.

Comprendre la correction

L’ordre est D,B,A,C,E. Les parents sont B pour A, A pour C et C pour E. Un second lancement depuis F couvre le sommet isolé, donc deux lancements au total suffisent. Relancer DFS depuis un sommet déjà marqué ne doit pas réexplorer sa composante ; la boucle extérieure consulte le même ensemble de découvertes.

Exercice 7 · Problème de synthèse#

Problème : diagnostiquer un marquage perdu

Un programme passe une copie vide de l’ensemble des visites à chaque appel dans le triangle A-B-C-A. Décrivez une suite d’appels qui ne progresse pas vers une fin. Proposez une correction et deux tests, dont un graphe sans cycle. Pourquoi le parent seul ne remplace-t-il pas les visites dans un cycle à trois sommets ?

Indice 1

Chaque appel oublie ce qui a déjà été découvert.

Indice 2

Éviter seulement le retour immédiat laisse A-B-C-A possible.

Comprendre la correction

Avec une mémoire vide, A appelle B, B rappelle A, et la répétition continue. Même en ignorant le parent, A-B-C-A referme le triangle. Il faut partager les découvertes et marquer avant les appels descendants. Testez le triangle, où chaque sommet est découvert une fois, puis une chaîne, où les retours n’ajoutent pas de découverte. Le marquage doit survivre aux changements de cadre.

Les erreurs qui méritent un détour

Oublier de marquer les sommets.
Les cycles et les retours d’arêtes peuvent provoquer des répétitions infinies.
Attendre un plus court chemin de DFS.
La profondeur privilégie une branche, pas les distances par couches.

La fiche à garder

L’essentiel à retenir

  • DFS approfondit une branche avant de revenir.
  • L’ordre des voisins doit être annoncé pour une trace unique.
  • Les visites mémorisées évitent de recommencer les mêmes explorations.

Cette notion au bac

Retrouvez ces idées dans un sujet complet, avec des indices, une correction expliquée et des ateliers.

Le prochain pas

Retrouver le catalogue de Terminale

Ce chapitre s’appuie sur le programme officiel de Terminale (PDF, nouvel onglet). Les explications et exercices sont proposés pour l’apprentissage.