Menu
Coddy logo textTech

Parcours en largeur (BFS)

Dernière mise à jour

Le parcours en largeur explore un graphe niveau par niveau. En partant d'un nœud source, il visite d'abord tous ses voisins immédiats, puis tous les voisins non visités de ceux-ci, et ainsi de suite - s'étendant vers l'extérieur en anneaux de distance croissante. Appuyez sur lecture ci-dessus pour le voir se déployer depuis le nœud de départ une couche à la fois.

Le BFS utilise une file de type premier entré, premier sorti, ce qui impose l'ordre niveau par niveau. Comme il atteint les nœuds dans l'ordre de la distance en sauts, le BFS trouve le plus court chemin (le moins d'arêtes) dans un graphe non pondéré. Il visite chaque nœud et chaque arête une fois, donc il s'exécute en temps O(V + E).

Complexité en temps et en espace

MesureComplexitéRemarques
TempsO(V + E)Chaque sommet et arête visité une fois
EspaceO(V)File + ensemble des visités, au pire cas tous les nœuds
ParcoursNiveau par niveauLes nœuds les plus proches d'abord, en anneaux
Plus court cheminOui (non pondéré)Atteint chaque nœud avec le moins d'arêtes

Étape par étape

ÉtapeCe qui se passe
1Enfile le nœud source.
2Défile le nœud en tête et marque-le comme visité.
3Examine chacun de ses voisins.
4Enfile tout voisin qui n'est pas déjà visité ou en file.
5Répète jusqu'à ce que la file soit vide.

Exemple résolu

Parcours de ce graphe depuis le nœud 0, où 0-1, 0-2, 1-3, 2-3, 2-4 sont des arêtes :

ÉtapeVisitésFile (frontière)
Début{}[0]
Défile 0{0}[1, 2]
Défile 1{0, 1}[2, 3]
Défile 2{0, 1, 2}[3, 4]
Défile 3{0, 1, 2, 3}[4]
Défile 4{0, 1, 2, 3, 4}[] (terminé)

Quand utiliser le BFS

Utilisez-le quandÉvitez-le quand
Vous avez besoin du plus court chemin dans un graphe non pondéréLes arêtes ont des poids - utilisez Dijkstra à la place
La cible est probablement proche de la sourceLe graphe est très large - la file peut contenir une frontière énorme
Vous voulez explorer un graphe dans l'ordre des niveauxVous devez seulement atteindre un nœud quelconque, où le DFS utilise moins de mémoire
Vous cherchez des composantes connexes ou un trajet à sauts minimauxVous avez besoin d'un tri topologique ou d'une détection de cycle - le DFS convient mieux

Une implémentation propre et exécutable de Breadth-First Search en Python, JavaScript, Java, C++, C. Choisissez un langage, copiez le code ou ouvrez-le préchargé dans le Playground Coddy.

Code de Breadth-First Search en Python

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")))
Exécutez ce code dans le Playground Python

FAQ sur le parcours en largeur

Quelle est la complexité temporelle du BFS ?
Le BFS s'exécute en temps O(V + E), où V est le nombre de sommets et E le nombre d'arêtes, puisqu'il visite chaque sommet une fois et examine chaque arête une fois. Il utilise O(V) d'espace pour la file et l'ensemble des visités.
Le BFS trouve-t-il le plus court chemin ?
Oui, dans un graphe non pondéré. Comme le BFS atteint les nœuds dans l'ordre de la distance en sauts depuis la source, la première fois qu'il atteint un nœud, c'est par un chemin comportant le moins d'arêtes. Pour les graphes pondérés, il vous faut l'algorithme de Dijkstra.
Quelle est la différence entre BFS et DFS ?
Le BFS utilise une file et explore niveau par niveau (les plus proches d'abord), tandis que le DFS utilise une pile et plonge en profondeur le long d'une branche avant de revenir en arrière. Le BFS trouve les plus courts chemins non pondérés ; le DFS utilise moins de mémoire sur les graphes larges et convient à la détection de cycles et au tri topologique.
Quand dois-je utiliser le BFS plutôt que l'algorithme de Dijkstra ?
Utilisez le BFS lorsque toutes les arêtes ont le même coût, car il trouve le chemin comportant le moins d'arêtes en temps O(V + E) sans file de priorité. L'algorithme de Dijkstra est nécessaire quand les arêtes portent des poids différents ; exécuter un BFS pur sur un graphe pondéré donne le chemin au moins de sauts, pas celui au moindre coût.
Pourquoi le BFS a-t-il besoin d'un ensemble des visités ?
Les graphes peuvent contenir des cycles, donc sans ensemble des visités le BFS enfilerait le même nœud à répétition et bouclerait à l'infini. Marquer un nœud lorsqu'on l'enfile pour la première fois (et non lorsqu'on le défile) empêche aussi le même nœud d'être ajouté deux fois à la file par des voisins différents.
Dois-je marquer un nœud comme visité à l'enfilage ou au défilage ?
Marquez-le à l'enfilage. Si vous attendez de le défiler, un nœud peut être ajouté plusieurs fois à la file par des voisins différents avant d'être traité, gaspillant mémoire et temps. Marquer à l'enfilage garantit que chaque nœud entre dans la file exactement une fois.
Coddy programming languages illustration

Maîtrisez les algorithmes avec Coddy

COMMENCER