Menu
Coddy logo textTech

Genişlik Öncelikli Arama (BFS)

Son güncelleme

Genişlik öncelikli arama bir grafı seviye seviye keşfeder. Bir kaynak düğümden başlayarak önce onun tüm doğrudan komşularını, sonra bunların ziyaret edilmemiş tüm komşularını ve böyle devam eder - artan uzaklıktaki halkalar halinde dışa doğru genişler. Yukarıda oynata basarak başlangıç düğümünden her seferinde bir katman şeklinde açıldığını izleyin.

BFS, seviye seviye sıralamayı dayatan ilk giren ilk çıkar (FIFO) bir kuyruk kullanır. Düğümlere sıçrama uzaklığı sırasına göre ulaştığı için, BFS ağırlıksız bir grafta en kısa yolu (en az kenar) bulur. Her düğümü ve kenarı bir kez ziyaret eder, bu yüzden O(V + E) zamanında çalışır.

Zaman ve alan karmaşıklığı

ÖlçütKarmaşıklıkNotlar
ZamanO(V + E)Her köşe ve kenar bir kez ziyaret edilir
AlanO(V)Kuyruk + ziyaret edilenler kümesi, en kötü durumda tüm düğümler
GezinmeSeviye seviyeEn yakın düğümler önce, halkalar halinde
En kısa yolEvet (ağırlıksız)Her düğüme en az kenarla ulaşır

Adım adım

AdımNe olur
1Kaynak düğümü kuyruğa ekle.
2Öndeki düğümü kuyruktan çıkar ve ziyaret edildi olarak işaretle.
3Komşularının her birine bak.
4Zaten ziyaret edilmemiş veya kuyrukta olmayan her komşuyu kuyruğa ekle.
5Kuyruk boşalana kadar tekrarla.

Çözümlü örnek

Bu grafta 0 düğümünden başlayarak gezinme, burada 0-1, 0-2, 1-3, 2-3, 2-4 kenarlardır:

AdımZiyaret edilenlerKuyruk (sınır)
Başlangıç{}[0]
0 çıkar{0}[1, 2]
1 çıkar{0, 1}[2, 3]
2 çıkar{0, 1, 2}[3, 4]
3 çıkar{0, 1, 2, 3}[4]
4 çıkar{0, 1, 2, 3, 4}[] (bitti)

BFS ne zaman kullanılır

Şu durumda kullanŞu durumda kaçın
Ağırlıksız bir grafta en kısa yola ihtiyacın varKenarların ağırlığı var - bunun yerine Dijkstra kullan
Hedef büyük olasılıkla kaynağa yakınGraf çok genişse - kuyruk devasa bir sınır tutabilir
Bir grafı seviye sırasında keşfetmek istiyorsunSadece herhangi bir düğüme ulaşman gerekiyor, burada DFS daha az bellek kullanır
Bağlı bileşenleri veya en az sıçramalı bir rota buluyorsunTopolojik sıralama veya döngü tespitine ihtiyacın var - DFS daha uygun

Breadth-First Search kodu

Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir Breadth-First Search uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.

Python ile Breadth-First Search kodu

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")))
Bu kodu Python Playground'da çalıştır

Genişlik Öncelikli Arama SSS

BFS'in zaman karmaşıklığı nedir?
BFS O(V + E) zamanında çalışır; burada V köşe sayısı, E ise kenar sayısıdır, çünkü her köşeyi bir kez ziyaret eder ve her kenarı bir kez inceler. Kuyruk ve ziyaret edilenler kümesi için O(V) alan kullanır.
BFS en kısa yolu bulur mu?
Evet, ağırlıksız bir grafta. BFS düğümlere kaynaktan sıçrama uzaklığı sırasına göre ulaştığı için, bir düğüme ilk ulaştığı an en az kenarlı yoldur. Ağırlıklı graflar için Dijkstra algoritmasına ihtiyacın var.
BFS ile DFS arasındaki fark nedir?
BFS bir kuyruk kullanır ve seviye seviye keşfeder (en yakınlar önce), DFS ise bir yığın kullanır ve geri dönmeden önce bir dal boyunca derine dalar. BFS ağırlıksız en kısa yolları bulur; DFS geniş graflarda daha az bellek kullanır ve döngü tespiti ile topolojik sıralamaya uygundur.
Dijkstra algoritması yerine BFS'i ne zaman kullanmalıyım?
Tüm kenarların maliyeti aynı olduğunda BFS'i kullan, çünkü öncelik kuyruğu olmadan en az kenarlı yolu O(V + E) zamanında bulur. Kenarların ağırlıkları farklı olduğunda Dijkstra algoritması gereklidir; ağırlıklı bir grafta saf BFS çalıştırmak en düşük maliyetli değil en az sıçramalı yolu verir.
BFS neden ziyaret edilenler kümesine ihtiyaç duyar?
Graflar döngü içerebilir, bu yüzden ziyaret edilenler kümesi olmadan BFS aynı düğümü tekrar tekrar kuyruğa ekler ve sonsuza dek döner. Bir düğümü ilk kuyruğa eklerken işaretlemek (çıkarırken değil) ayrıca aynı düğümün farklı komşular tarafından kuyruğa iki kez eklenmesini önler.
Bir düğümü kuyruğa eklerken mi yoksa çıkarırken mi ziyaret edildi olarak işaretlemeliyim?
Kuyruğa eklerken işaretle. Çıkarana kadar beklersen, bir düğüm işlenmeden önce farklı komşular tarafından kuyruğa birden çok kez eklenebilir, bu da bellek ve zaman israfına yol açar. Eklerken işaretlemek her düğümün kuyruğa tam olarak bir kez girmesini garanti eder.
Coddy programming languages illustration

Coddy ile algoritmalarda ustalaş

BAŞLA