Menu
Coddy logo textTech

BFS (przeszukiwanie wszerz)

Ostatnia aktualizacja

Przeszukiwanie wszerz przegląda graf poziom po poziomie. Zaczynając od węzła źródłowego, najpierw odwiedza wszystkich jego bezpośrednich sąsiadów, potem wszystkich ich nieodwiedzonych sąsiadów i tak dalej, rozszerzając się na zewnątrz pierścieniami o rosnącej odległości. Kliknij odtwarzanie powyżej i zobacz, jak algorytm rozchodzi się od węzła startowego warstwa po warstwie.

BFS używa kolejki FIFO (pierwszy wszedł, pierwszy wyszedł) i to ona wymusza kolejność poziom po poziomie. Ponieważ BFS dociera do węzłów w kolejności liczby przeskoków, znajduje najkrótszą ścieżkę (najmniej krawędzi) w grafie bez wag. Odwiedza każdy węzeł i każdą krawędź raz, więc działa w czasie O(V + E).

Złożoność czasowa i pamięciowa

MiaraZłożonośćUwagi
CzasO(V + E)Każdy wierzchołek i krawędź odwiedzane raz
PamięćO(V)Kolejka + zbiór odwiedzonych, w najgorszym razie wszystkie węzły
PrzechodzeniePoziom po poziomieNajpierw najbliższe węzły, pierścieniami
Najkrótsza ścieżkaTak (bez wag)Dociera do każdego węzła najmniejszą liczbą krawędzi

Krok po kroku

KrokCo się dzieje
1Dodaj węzeł źródłowy do kolejki.
2Pobierz węzeł z początku kolejki i oznacz go jako odwiedzony.
3Przejrzyj każdego z jego sąsiadów.
4Dodaj do kolejki każdego sąsiada, który nie był jeszcze odwiedzony ani dodany.
5Powtarzaj, aż kolejka będzie pusta.

Przykład krok po kroku

Przechodzenie tego grafu od węzła 0, gdzie krawędzie to 0-1, 0-2, 1-3, 2-3, 2-4:

KrokOdwiedzoneKolejka (granica)
Start{}[0]
Pobierz 0{0}[1, 2]
Pobierz 1{0, 1}[2, 3]
Pobierz 2{0, 1, 2}[3, 4]
Pobierz 3{0, 1, 2, 3}[4]
Pobierz 4{0, 1, 2, 3, 4}[] (koniec)

Kiedy używać BFS

Używaj, gdyUnikaj, gdy
Potrzebujesz najkrótszej ścieżki w grafie bez wagKrawędzie mają wagi: użyj algorytmu Dijkstry
Cel prawdopodobnie leży blisko źródłaGraf jest bardzo szeroki: kolejka może pomieścić ogromną granicę
Chcesz przeglądać graf w kolejności poziomówWystarczy dotrzeć do dowolnego węzła, a DFS zużywa mniej pamięci
Szukasz spójnych składowych lub trasy z najmniejszą liczbą przeskokówPotrzebujesz sortowania topologicznego lub wykrywania cykli: DFS pasuje lepiej

BFS a DFS

Oba odwiedzają każdy węzeł w O(V + E), ale różnią się kolejnością i strukturą danych. Zobacz wizualizację przeszukiwania w głąb, aby porównać je obok siebie.

AspektBFSDFS
Struktura danychKolejka (FIFO)Stos / rekurencja
KolejnośćPoziom po poziomie (najpierw najbliższe)W głąb jednej gałęzi, potem powrót
Najkrótsza ścieżka (bez wag)Tak: najmniej krawędziNie: brak gwarancji
Pamięć w szerokich grafachDuża: granica może być ogromnaMała: jedna ścieżka naraz
Najlepszy doNajmniejszej liczby przeskoków, spójnych składowychWykrywania cykli, sortowania topologicznego, backtrackingu

Breadth-First Search: kod

Przejrzysta, gotowa do uruchomienia implementacja algorytmu Breadth-First Search w językach: Python, JavaScript, Java, C++, C. Wybierz język, skopiuj kod albo otwórz go od razu w edytorze online Coddy.

Breadth-First Search: kod (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")))
Uruchom ten kod w edytorze Python online

BFS (przeszukiwanie wszerz): najczęstsze pytania

Jaka jest złożoność czasowa BFS?
BFS działa w czasie O(V + E), gdzie V to liczba wierzchołków, a E liczba krawędzi, bo każdy wierzchołek odwiedza raz i każdą krawędź sprawdza raz. Zużywa O(V) pamięci na kolejkę i zbiór odwiedzonych.
Czy BFS znajduje najkrótszą ścieżkę?
Tak, w grafie bez wag. Ponieważ BFS dociera do węzłów w kolejności liczby przeskoków od źródła, pierwsze dotarcie do węzła następuje ścieżką z najmniejszą liczbą krawędzi. W grafach ważonych potrzebujesz algorytmu Dijkstry.
Czym różni się BFS od DFS?
BFS używa kolejki i przegląda graf poziom po poziomie (najpierw najbliższe), a DFS używa stosu i schodzi głęboko w jedną gałąź, zanim się wycofa. BFS znajduje najkrótsze ścieżki bez wag; DFS zużywa mniej pamięci w szerokich grafach i nadaje się do wykrywania cykli oraz sortowania topologicznego.
Kiedy użyć BFS zamiast algorytmu Dijkstry?
Użyj BFS, gdy każda krawędź ma ten sam koszt, bo znajduje ścieżkę z najmniejszą liczbą krawędzi w czasie O(V + E) bez kolejki priorytetowej. Algorytm Dijkstry jest potrzebny, gdy krawędzie mają różne wagi; zwykłe BFS na grafie ważonym daje ścieżkę z najmniejszą liczbą przeskoków, a nie najtańszą.
Dlaczego BFS potrzebuje zbioru odwiedzonych węzłów?
Grafy mogą zawierać cykle, więc bez zbioru odwiedzonych BFS dodawałby ten sam węzeł do kolejki wielokrotnie i zapętlił się w nieskończoność. Oznaczanie węzła przy pierwszym dodaniu do kolejki (a nie przy pobraniu) zapobiega też dodaniu tego samego węzła dwa razy przez różnych sąsiadów.
Oznaczać węzeł jako odwiedzony przy dodaniu do kolejki czy przy pobraniu?
Oznaczaj go przy dodaniu do kolejki. Jeśli poczekasz do pobrania, węzeł może zostać dodany do kolejki wiele razy przez różnych sąsiadów, zanim zostanie przetworzony, co marnuje pamięć i czas. Oznaczanie przy dodaniu gwarantuje, że każdy węzeł trafi do kolejki dokładnie raz.
Ilustracja języków programowania w Coddy

Opanuj algorytmy z Coddy

ZACZNIJ