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çüt | Karmaşıklık | Notlar |
|---|---|---|
| Zaman | O(V + E) | Her köşe ve kenar bir kez ziyaret edilir |
| Alan | O(V) | Kuyruk + ziyaret edilenler kümesi, en kötü durumda tüm düğümler |
| Gezinme | Seviye seviye | En yakın düğümler önce, halkalar halinde |
| En kısa yol | Evet (ağırlıksız) | Her düğüme en az kenarla ulaşır |
Adım adım
| Adım | Ne olur |
|---|---|
| 1 | Kaynak düğümü kuyruğa ekle. |
| 2 | Öndeki düğümü kuyruktan çıkar ve ziyaret edildi olarak işaretle. |
| 3 | Komşularının her birine bak. |
| 4 | Zaten ziyaret edilmemiş veya kuyrukta olmayan her komşuyu kuyruğa ekle. |
| 5 | Kuyruk 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ım | Ziyaret edilenler | Kuyruk (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 var | Kenarların ağırlığı var - bunun yerine Dijkstra kullan |
| Hedef büyük olasılıkla kaynağa yakın | Graf çok genişse - kuyruk devasa bir sınır tutabilir |
| Bir grafı seviye sırasında keşfetmek istiyorsun | Sadece 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 buluyorsun | Topolojik 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
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")))JavaScript ile Breadth-First Search kodu
1const graph = {2 A: ["B", "C"],3 B: ["D", "E"],4 C: ["F"],5 D: [],6 E: ["F"],7 F: [],8};9
10function bfs(start) {11 const visited = new Set([start]);12 const queue = [start];13 const order = [];14 while (queue.length > 0) {15 const node = queue.shift(); // Dequeue the oldest node16 order.push(node);17 for (const next of graph[node]) {18 if (!visited.has(next)) {19 visited.add(next);20 queue.push(next);21 }22 }23 }24 return order;25}26
27console.log("BFS from A:", bfs("A").join(" -> "));Java ile Breadth-First Search kodu
1import java.util.ArrayDeque;2import java.util.List;3import java.util.Queue;4
5public class Main {6 public static void main(String[] args) {7 List<List<Integer>> adj = List.of(8 List.of(1, 2), // neighbors of 09 List.of(0, 3, 4), // neighbors of 110 List.of(0, 5),11 List.of(1),12 List.of(1, 5),13 List.of(2, 4)14 );15 boolean[] visited = new boolean[adj.size()];16 Queue<Integer> queue = new ArrayDeque<>();17 visited[0] = true;18 queue.add(0);19
20 StringBuilder order = new StringBuilder("BFS from 0:");21 while (!queue.isEmpty()) {22 int node = queue.poll();23 order.append(" ").append(node);24 // Mark neighbors when enqueued so nothing enters twice25 for (int next : adj.get(node)) {26 if (!visited[next]) {27 visited[next] = true;28 queue.add(next);29 }30 }31 }32 System.out.println(order);33 }34}C++ ile Breadth-First Search kodu
1#include <iostream>2#include <queue>3#include <vector>4
5void bfs(int start, const std::vector<std::vector<int>>& adj) {6 std::vector<bool> visited(adj.size(), false);7 std::queue<int> frontier;8 visited[start] = true;9 frontier.push(start);10 // Visit nodes level by level11 while (!frontier.empty()) {12 int node = frontier.front();13 frontier.pop();14 std::cout << node << " ";15 for (int next : adj[node]) {16 if (!visited[next]) {17 visited[next] = true;18 frontier.push(next);19 }20 }21 }22}23
24int main() {25 // 6-node undirected graph as an adjacency list26 std::vector<std::vector<int>> adj = {27 {1, 2}, // 028 {0, 3, 4}, // 129 {0, 5}, // 230 {1}, // 331 {1, 5}, // 432 {2, 4}, // 533 };34 std::cout << "BFS from node 0: ";35 bfs(0, adj);36 std::cout << "\n";37 return 0;38}C ile Breadth-First Search kodu
1#include <stdbool.h>2#include <stdio.h>3
4#define N 65
6void bfs(int start, const int adj[N][N]) {7 bool visited[N] = {false};8 int queue[N]; // fixed-size queue: head chases tail9 int head = 0, tail = 0;10 visited[start] = true;11 queue[tail++] = start;12 // Visit nodes level by level13 while (head < tail) {14 int node = queue[head++];15 printf("%d ", node);16 for (int next = 0; next < N; next++) {17 if (adj[node][next] && !visited[next]) {18 visited[next] = true;19 queue[tail++] = next;20 }21 }22 }23}24
25int main(void) {26 // 6-node undirected graph as an adjacency matrix27 int adj[N][N] = {28 {0, 1, 1, 0, 0, 0},29 {1, 0, 0, 1, 1, 0},30 {1, 0, 0, 0, 0, 1},31 {0, 1, 0, 0, 0, 0},32 {0, 1, 0, 0, 0, 1},33 {0, 0, 1, 0, 1, 0},34 };35 printf("BFS from node 0: ");36 bfs(0, adj);37 printf("\n");38 return 0;39}Genişlik Öncelikli Arama SSS
BFS'in zaman karmaşıklığı nedir?
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?
BFS ile DFS arasındaki fark nedir?
Dijkstra algoritması yerine BFS'i ne zaman kullanmalıyım?
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.