Bölüm 4.1: Çizge Gezinme Algoritmaları

Algoritmalar
Çizge türleriGösterimDerinlik öncelikli arama (DFS)Genişlik öncelikli arama (BFS) Labirent ve en kısa yolTarjan SCCTopolojik sıralamaKarmaşıklık
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Çizge kavramları

Yönlü, yönsüz, ağırlıklı, iki parçalı, tam çizge ve ağaç türlerini ayırt etmek; komşuluk listesi ve matrisiyle göstermek.

DFS

Derinlik öncelikli aramayı özyinelemeli ve yığınla yazmak, ziyaret sırasını adım adım çıkarmak, geri izlemeyi açıklamak.

BFS

Genişlik öncelikli aramayı kuyrukla yazmak; katman, ata ve ağırlıksız en kısa yol kavramlarını labirent örneğinde uygulamak.

Tarjan ve analiz

Güçlü bağlantılı bileşenleri indeks / enDüşükBağ değerleriyle bulmak; tüm gezinme algoritmalarının O(V + E) zamanını gerekçelendirmek.

Giriş

Çizgeler Her Yerde

  • Dünya bir ağ gibidir: şehirler yollarla, insanlar ilişkilerle, bilgisayarlar kablolarla birbirine bağlıdır.
  • Çizge (graph) G = (V, E): düğümler (vertex, V) ve onları birleştiren kenarlar (edge, E).
  • Çizge algoritmaları bu ağları inceler ve anlamlandırır: en kısa yol, gruplama, bağlantılılık, akış…
  • Kullanım: sosyal ağlar, harita ve navigasyon, ağ yönlendirme, derleyiciler, oyunlar.
OrduGiresunTrabzonSamsunSivasErzurum

Şehirler düğüm, yollar kenar.

Bu bölümde V = düğüm sayısı, E = kenar sayısı. Karmaşıklıklar bu iki sayı cinsinden verilir: O(V + E), O(V²)…

Giriş

Çizge Türleri

ABCDYönlü (directed)

Kenarlar yalnızca ok yönünde geçilir.

ABCDYönsüz (undirected)

Kenarlar iki yönde de geçilir.

8312ABCDAğırlıklı (weighted)

Her kenara bir ağırlık (maliyet, uzaklık) atanır.

İki parçalı (bipartite)

Kenarlar yalnızca farklı kümelerdeki düğümleri bağlar.

ADEBCDöngülü (cyclic)

A–D–C–B–A gibi başladığı yere dönen bir yol vardır.

ADEBCAğaç (tree)

Bağlı ve döngüsüz; iki düğüm arasında tek yol.

ABCDTam (complete)

Her düğüm çifti bir kenarla bağlı: n(n−1)/2 kenar.

ABBasit olmayan

Çoklu kenar ve öz döngü içerir; basit çizge içermez.

Giriş

Çizge Algoritmalarının Çeşitleri

1 · Gezinme (graph traversal)

DFS bir düğümden başlayıp dallanarak, BFS katman katman tüm ağı gezer. Bu bölüm.

2 · En kısa yol (shortest path)

Dijkstra: başlangıçtan diğer tüm düğümlere en kısa yollar. Bölüm 4.2.

3 · Minimum kapsayan ağaç (MST)

Kruskal: ağı minimum toplam maliyetle bağlayan kenarları seçer. Bölüm 4.3.

4 · Ağ akışı (network flow)

Kapasiteli bir ağda kaynaktan hedefe gönderilebilecek en büyük akış. Bölüm 4.4.

AlgoritmaGünlük örnek
DFSBir labirentten çıkış yolu ararken bir koridoru sonuna kadar izleyip geri dönmek
BFSBir haberin şehirde kişiden kişiye yayılması: önce yakın çevre, sonra onların çevresi
DijkstraBir kuryenin en kısa sürede teslimat yapacağı rotayı bulmak

Giriş

Çizgeyi Bellekte Tutmak

0123

V = 4, E = 4

Komşuluk listesi

0: 1, 2
1: 0, 2
2: 0, 1, 3
3: 2

Komşuluk matrisi

0123
00110
11010
21101
30010
Komşuluk listesiKomşuluk matrisi
BellekO(V + E)O(V²)
u'nun tüm komşularıO(derece(u))O(V)
(u, v) kenarı var mı?O(derece(u))O(1)
Gezinme (DFS / BFS)O(V + E)O(V²)

Bu bölümdeki Java kodları komşuluk listesi kullanır: List<Integer>[] komsu.

Gezinme

Çizge Gezinme

  • Gezinme (graph traversal), çizgenin yapısını sistematik biçimde keşfetmek için her düğümü (ulaşılabiliyorsa) tam bir kez ziyaret eder.
  • İki ana yaklaşım vardır; fark, sıradaki düğümün hangi veri yapısından alındığıdır:
Derinlik Öncelikli Arama (DFS, Depth-First Search)

Yığıt (stack, LIFO) kullanır. Bir düğümden başlar, mümkün olduğunca derine iner; komşuları bitince geri döner (backtracking).

Genişlik Öncelikli Arama (BFS, Breadth-First Search)

Kuyruk (queue, FIFO) kullanır. Başlangıca uzaklığı 1 olanları, sonra 2 olanları… seviye seviye ziyaret eder.

Ziyaret dizisi şart: çizgede döngü olabilir (ağaçtan farkı budur). ziyaret[] işaretlenmezse algoritma aynı döngüde sonsuza kadar dolaşır.

DFS

DFS: Fikir

  • Labirentte bir koridora gir, çıkmaza kadar ilerle; çıkmazda son yol ayrımına geri dön ve henüz denenmemiş koridoru seç.
  • Özyinelemeli sürümde geri dönüş noktalarını çağrı yığını hatırlar; yinelemeli sürümde açık bir yığıt kullanılır.
  • Ziyaret edilen düğümler ve onlara ilk ulaşılan kenarlar bir DFS ağacı oluşturur.
  • Ziyaret sırası komşuların sırasına bağlıdır; aynı çizgede farklı ama geçerli DFS sıraları vardır.
Düğüm durumları

beyaz: henüz keşfedilmedi
sarı: keşfedildi, işi sürüyor (yığında)
koyu: bitti, tüm komşuları incelendi

DFS soruları: "ulaşılabilir mi?", "döngü var mı?", "kaç bileşen var?", "hangi sırayla yapılmalı?" (topolojik sıra), "güçlü bağlantılı bileşenler neler?" (Tarjan).

DFS · Adım adım

DFS Adım Adım: Ziyaret Sırası

Yığın (özyineleme): boş

Başlangıç: hiçbir düğüm ziyaret edilmedi. DFS kökten başlayacak; düğümlere ziyaret sırası numarası yazılacak.

1Yığın (özyineleme): 1

Kök ziyaret edilir (1). Komşulardan ilki seçilip derine inilecek.

12Yığın (özyineleme): 1 → 2

1 düğümünün ilk keşfedilmemiş komşusuna inilir: 2. Yığın derinleşir.

123Yığın (özyineleme): 1 → 2 → 3

2 düğümünün ilk keşfedilmemiş komşusuna inilir: 3. Yığın derinleşir.

1234Yığın (özyineleme): 1 → 2 → 3 → 4

3 düğümünün ilk keşfedilmemiş komşusuna inilir: 4. Yığın derinleşir.

12534Yığın (özyineleme): 1 → 5

4, 3, 2 düğümlerinin keşfedilmemiş komşusu kalmadı → geri dönüldü (backtrack). 1 düğümünün sıradaki çocuğu ziyaret edilir: 5.

125364Yığın (özyineleme): 1 → 5 → 6

5 düğümünün ilk keşfedilmemiş komşusuna inilir: 6. Yığın derinleşir.

1253647Yığın (özyineleme): 1 → 5 → 6 → 7

6 düğümünün ilk keşfedilmemiş komşusuna inilir: 7. Yığın derinleşir.

12536847Yığın (özyineleme): 1 → 5 → 8

7, 6 düğümlerinin keşfedilmemiş komşusu kalmadı → geri dönüldü (backtrack). 5 düğümünün sıradaki çocuğu ziyaret edilir: 8.

125936847Yığın (özyineleme): 1 → 9

8, 5 düğümlerinin keşfedilmemiş komşusu kalmadı → geri dönüldü (backtrack). 1 düğümünün sıradaki çocuğu ziyaret edilir: 9.

12593681047Yığın (özyineleme): 1 → 9 → 10

9 düğümünün ilk keşfedilmemiş komşusuna inilir: 10. Yığın derinleşir.

12593681047Yığın (özyineleme): boş

Tüm düğümler ziyaret edildi; yığın boşaldı. Ziyaret sırası: 1, 2, 3, …, 10: her dal sonuna kadar izlenip sonra geri dönüldü.

DFS

Özyinelemeli DFS: Sözde Kod

İngilizce sözde kod

procedure DFS(G, v) is
  label v as discovered
  for all directed edges from v to w
      that are in G.adjacentEdges(v) do
    if vertex w is not labeled
        as discovered then
      call DFS(G, w)

Türkçe

DFS(düğüm, ziyaretEdilenler):
  eğer düğüm ziyaretEdilenler
        içinde değilse:
    düğüm'ü ziyaretEdilenler'e ekle
    düğüm'ü işle (örneğin, yazdır)
    her bir komşu düğüm için:
      DFS(komşu, ziyaretEdilenler)
  • Soldaki sürüm komşuyu çağırmadan önce, sağdaki çağrının başında denetler; ikisi aynı sırayı üretir. Sağdakinde gereksiz çağrılar yapılır ama hemen döner.
  • Bağlı olmayan bir çizgede tüm düğümleri gezmek için DFS, ziyaret edilmemiş her düğümden yeniden başlatılır (her başlatma bir bağlı bileşen).

DFS

Yinelemeli DFS: Sözde Kod

İngilizce sözde kod

procedure DFS_iterative(G, v) is
  let S be a stack
  S.push(v)
  while S is not empty do
    v = S.pop()
    if v is not labeled as discovered then
      label v as discovered
      for all edges from v to w
          in G.adjacentEdges(v) do
        S.push(w)

Türkçe

DFS(başlangıç_düğüm):
  boş bir yığın oluştur
  başlangıç_düğüm'ü yığına ekle
  döngü yığın boş değilken:
    mevcut_düğüm = yığından çıkar
    eğer mevcut_düğüm ziyaretEdilenler
          içinde değilse:
      mevcut_düğüm'ü ziyaretEdilenler'e ekle
      her bir komşu_düğüm için:
        komşu_düğüm'ü yığına ekle
  • Özyineleme yerine açık bir yığın: çok derin çizgelerde StackOverflowError riski yoktur.
  • İşaretleme çekerken yapılır; bu yüzden bir düğüm yığına birden çok kez girebilir (yığın boyutu O(E)).
  • Komşular itildiği için en son itilen önce çıkar: sıra, özyinelemeli sürümün tersine döner. Aynı sıra istenirse komşular ters sırada itilir.

DFS · Kodu adım adım çalıştır

Özyinelemeli DFS: dfs(0) İzleme

01273456

Örnek yönlü çizge: 0→1, 0→2, 0→7, 1→2, 2→0, 2→3, 2→4, 3→5, 4→6, 5→6. dfs(0): 0 işaretlenir, yazdırılır.

01273456

0'ın komşusu 1 ziyaret edilmemiş → dfs(1): işaretlenir, yazdırılır. Yığına yeni çerçeve eklendi.

01273456

1'in komşusu 2 ziyaret edilmemiş → dfs(2): işaretlenir, yazdırılır. Yığına yeni çerçeve eklendi.

01273456

2'nin komşusu 0 zaten ziyaret edildi → atlanır (döngüye girilmez).

01273456

2'nin komşusu 3 ziyaret edilmemiş → dfs(3): işaretlenir, yazdırılır. Yığına yeni çerçeve eklendi.

01273456

3'ün komşusu 5 ziyaret edilmemiş → dfs(5): işaretlenir, yazdırılır. Yığına yeni çerçeve eklendi.

01273456

5'in komşusu 6 ziyaret edilmemiş → dfs(6): işaretlenir, yazdırılır. Yığına yeni çerçeve eklendi.

01273456

6, 5, 3 bitti (komşu kalmadı) → çağrı(lar) döner, kontrol 2'ye geri gelir: geri izleme.

01273456

2'nin komşusu 4 ziyaret edilmemiş → dfs(4): işaretlenir, yazdırılır. Yığına yeni çerçeve eklendi.

01273456

4'ün komşusu 6 zaten ziyaret edildi → atlanır (döngüye girilmez).

01273456

4, 2, 1 bitti (komşu kalmadı) → çağrı(lar) döner, kontrol 0'a geri gelir: geri izleme.

01273456

0'ın komşusu 2 zaten ziyaret edildi → atlanır (döngüye girilmez).

01273456

0'ın komşusu 7 ziyaret edilmemiş → dfs(7): işaretlenir, yazdırılır. Yığına yeni çerçeve eklendi.

01273456

7, 0 bitti; dfs(0) da döner. Çıktı: 0 1 2 3 5 6 4 7. Kalın kenarlar DFS ağacını oluşturur.

void dfs(int v, boolean[] ziyaret) {
  ziyaret[v] = true;
  System.out.print(v + " ");
  for (int w : komsu[v])
    if (!ziyaret[w])
      dfs(w, ziyaret);
}

DFS · Kodu adım adım çalıştır

Yığınla DFS: dfsYigin(0) İzleme

01273456yığın (alt → üst)0

Başlangıç düğümü 0 yığına itilir. Henüz hiçbir düğüm işaretli değil.

01273456yığın (alt → üst)127

0 çekildi: işaretlenir, yazdırılır; komşuları 1, 2, 7 sırayla itilir → en son itilen 7 en üstte.

01273456yığın (alt → üst)12

7 çekildi: işaretlenir, yazdırılır; komşusu yok, yığına bir şey eklenmez.

01273456yığın (alt → üst)1034

2 çekildi: işaretlenir, yazdırılır; komşuları 0, 3, 4 sırayla itilir → en son itilen 4 en üstte.

01273456yığın (alt → üst)1036

4 çekildi: işaretlenir, yazdırılır; komşusu 6 itilir → en son itilen 6 en üstte.

01273456yığın (alt → üst)103

6 çekildi: işaretlenir, yazdırılır; komşusu yok, yığına bir şey eklenmez.

01273456yığın (alt → üst)105

3 çekildi: işaretlenir, yazdırılır; komşusu 5 itilir → en son itilen 5 en üstte.

01273456yığın (alt → üst)106

5 çekildi: işaretlenir, yazdırılır; komşusu 6 itilir → en son itilen 6 en üstte.

01273456yığın (alt → üst)10

6 çekildi ama zaten ziyaret edilmiş → hiçbir şey yapılmaz. (Bir düğüm yığına birden çok kez girebilir.)

01273456yığın (alt → üst)1

0 çekildi ama zaten ziyaret edilmiş → hiçbir şey yapılmaz. (Bir düğüm yığına birden çok kez girebilir.)

01273456yığın (alt → üst)2

1 çekildi: işaretlenir, yazdırılır; komşusu 2 itilir → en son itilen 2 en üstte.

01273456yığın (alt → üst)

2 çekildi ama zaten ziyaret edilmiş → hiçbir şey yapılmaz. (Bir düğüm yığına birden çok kez girebilir.)

01273456yığın (alt → üst)

Yığın boş, döngü biter. Çıktı: 0 7 2 4 6 3 5 1: özyinelemeli sürümden (0 1 2 3 5 6 4 7) farklı, çünkü komşular ters sırada çıkar.

void dfsYigin(int s) {
  boolean[] ziyaret = new boolean[n];
  Deque<Integer> yigin = new ArrayDeque<>();
  yigin.push(s);
  while (!yigin.isEmpty()) {
    int v = yigin.pop();
    if (!ziyaret[v]) {
      ziyaret[v] = true;
      System.out.print(v + " ");
      for (int w : komsu[v])
        yigin.push(w);
    }
  }
}

DFS

DFS: Analiz ve Kullanım

Karmaşıklık

  • Her düğüm bir kez işaretlenir: O(V).
  • Her düğümün komşu listesi bir kez taranır; listelerin toplam uzunluğu E (yönsüzde 2E): O(E).
  • Toplam: O(V + E) (komşuluk listesi), O(V²) (matris: her düğüm için V elemanlı satır).
  • Ek bellek: ziyaret[] O(V) + yığın: özyinelemede en uzun yol kadar, O(V); "çekerken işaretle" sürümünde O(E).

Nerede kullanılır?

  • Ulaşılabilirlik, bağlı bileşen sayısı
  • Döngü tespiti: yığındaki (sarı) bir düğüme giden kenar = geri kenar
  • Topolojik sıralama: bitiş sırasının tersi
  • Güçlü bağlantılı bileşenler (Tarjan, Kosaraju)
  • Köprü ve eklem noktaları, labirent ve bulmaca çözme, geri izleme (backtracking)
DFS en kısa yolu bulmaz: hedefe ilk ulaştığı yol çok uzun bir dolambaç olabilir. En az kenarlı yol için BFS gerekir.

BFS

BFS: Fikir

  • Suya atılan taşın dalgası gibi: önce başlangıca 1 kenar uzaktakiler, sonra 2 kenar uzaktakiler…
  • Bir haberin yayılmasını modeller: kişi haberi tüm arkadaşlarına söyler, onlar da kendi arkadaşlarına.
  • Kuyruk (FIFO) sırayı korur: önce keşfedilen önce işlenir.
  • Düğüm kuyruğa girerken işaretlenir; böylece her düğüm kuyruğa en fazla bir kez girer.
  • Ağırlıksız çizgede başlangıçtan her düğüme en az kenarlı yolu bulur.
Katmanlar (levels)

L0 = {s}
L1 = s'nin komşuları
L2 = L1'in yeni komşuları
…
Lk'deki her düğümün s'ye uzaklığı tam k'dir.

BFS · Adım adım

BFS Adım Adım: Katman Katman

12675384kuyrukişlenen sıra: —

Başlangıç: tüm düğümler beyaz (keşfedilmedi). Sarı = keşfedildi, kuyrukta bekliyor · koyu = işlendi.

12675384kuyruk1işlenen sıra: —

Başlangıç düğümü 1 keşfedildi olarak işaretlenir ve kuyruğa konur.

12675384kuyruk2345işlenen sıra: 1

Kuyruktan 1 alınır; keşfedilmemiş komşuları 2, 3, 4, 5 işaretlenip kuyruğa eklenir (1. katman).

12675384kuyruk34567işlenen sıra: 1 2

Kuyruktan 2 alınır; keşfedilmemiş komşuları 6, 7 işaretlenip kuyruğa eklenir (2. katman).

12675384kuyruk45678işlenen sıra: 1 2 3

Kuyruktan 3 alınır; keşfedilmemiş komşusu 8 işaretlenip kuyruğa eklenir (2. katman).

12675384kuyruk5678işlenen sıra: 1 2 3 4

Kuyruktan 4 alınır; keşfedilmemiş komşusu yok.

12675384kuyruk678işlenen sıra: 1 2 3 4 5

Kuyruktan 5 alınır; keşfedilmemiş komşusu yok.

12675384kuyruk78işlenen sıra: 1 2 3 4 5 6

Kuyruktan 6 alınır; keşfedilmemiş komşusu yok.

12675384kuyruk8işlenen sıra: 1 2 3 4 5 6 7

Kuyruktan 7 alınır; keşfedilmemiş komşusu yok.

12675384kuyrukişlenen sıra: 1 2 3 4 5 6 7 8

Kuyruktan 8 alınır; keşfedilmemiş komşusu yok → kuyruk boşaldı, BFS biter.

12675384kuyrukişlenen sıra: 1 2 3 4 5 6 7 8

Sonuç: ziyaret sırası 1, 2, 3, 4, 5, 6, 7, 8. Önce uzaklığı 1 olanlar (2, 3, 4, 5), sonra uzaklığı 2 olanlar (6, 7, 8): katman katman.

BFS

BFS: Sözde Kod

İngilizce sözde kod

procedure BFS(G, root) is
  let Q be a queue
  label root as explored
  Q.enqueue(root)
  while Q is not empty do
    v := Q.dequeue()
    for all edges from v to w
        in G.adjacentEdges(v) do
      if w is not labeled as explored then
        label w as explored
        w.parent := v
        Q.enqueue(w)

Türkçe

BFS(başlangıç_düğüm):
  boş bir kuyruk oluştur
  başlangıç_düğüm'ü keşfedildi işaretle
  başlangıç_düğüm'ü kuyruğa koy
  döngü kuyruk boş değilken:
    mevcut_düğüm = kuyruktan al
    her bir komşu_düğüm için
      eğer komşu_düğüm keşfedilmemiş ise
        komşu_düğüm'ü keşfedildi işaretle
        komşu_düğüm'ün atası = mevcut_düğüm
        komşu_düğüm'ü kuyruğa koy
  • w.parent := v (ata) bağlantıları BFS ağacını oluşturur; hedeften köke doğru izlenince en kısa yol elde edilir.
  • İşaretleme kuyruğa eklerken yapılır, çıkarırken değil: aksi hâlde aynı düğüm kuyruğa defalarca girer.

BFS · Kodu adım adım çalıştır

BFS: bfs(0) İzleme

01273456kuyruk (ön → arka)0

0 işaretlenir ve kuyruğa eklenir. Kuyruk yalnızca 0'ı içerir.

01273456kuyruk (ön → arka)

Kuyruğun önünden 0 alınır ve yazdırılır.

01273456kuyruk (ön → arka)127

0'ın komşuları: keşfedilmemiş komşular 1, 2, 7 işaretlenip kuyruğun arkasına eklenir.

01273456kuyruk (ön → arka)27

Kuyruğun önünden 1 alınır ve yazdırılır.

01273456kuyruk (ön → arka)27

1'in komşuları: 2 zaten işaretli → atlanır.

01273456kuyruk (ön → arka)7

Kuyruğun önünden 2 alınır ve yazdırılır.

01273456kuyruk (ön → arka)734

2'nin komşuları: keşfedilmemiş komşular 3, 4 işaretlenip kuyruğun arkasına eklenir; 0 zaten işaretli → atlanır.

01273456kuyruk (ön → arka)34

Kuyruğun önünden 7 alınır ve yazdırılır.

01273456kuyruk (ön → arka)4

Kuyruğun önünden 3 alınır ve yazdırılır.

01273456kuyruk (ön → arka)45

3'ün komşuları: keşfedilmemiş komşu 5 işaretlenip kuyruğun arkasına eklenir.

01273456kuyruk (ön → arka)5

Kuyruğun önünden 4 alınır ve yazdırılır.

01273456kuyruk (ön → arka)56

4'ün komşuları: keşfedilmemiş komşu 6 işaretlenip kuyruğun arkasına eklenir.

01273456kuyruk (ön → arka)6

Kuyruğun önünden 5 alınır ve yazdırılır.

01273456kuyruk (ön → arka)6

5'in komşuları: 6 zaten işaretli → atlanır.

01273456kuyruk (ön → arka)

Kuyruğun önünden 6 alınır ve yazdırılır.

01273456kuyruk (ön → arka)

Kuyruk boş. Çıktı: 0 1 2 7 3 4 5 6, katman katman: {0}, {1, 2, 7}, {3, 4}, {5, 6}. Kalın kenarlar BFS ağacıdır.

void bfs(int s) {
  boolean[] ziyaret = new boolean[n];
  Queue<Integer> kuyruk = new LinkedList<>();
  ziyaret[s] = true; kuyruk.add(s);
  while (!kuyruk.isEmpty()) {
    int v = kuyruk.poll();
    System.out.print(v + " ");
    for (int w : komsu[v])
      if (!ziyaret[w]) {
        ziyaret[w] = true;
        kuyruk.add(w);
      }
  }
}

BFS · Adım adım

BFS ile Labirent: Tüm Yolları Eşzamanlı Dene

0▸◂giriş: sol üstçıkış:sağ alt

Giriş hücresi uzaklık 0 ile kuyruğa konur. Duvarlar (koyu) çizgede düğüm değildir; her boş hücre bir düğüm, komşu boş hücreler kenardır.

012▸◂giriş: sol üstçıkış:sağ alt

Dalga her adımda tüm yönlere bir hücre ilerler: uzaklığı 1 ve 2 olan hücreler. Sarı = şu anki sınır (frontier).

01234▸◂giriş: sol üstçıkış:sağ alt

Tek koridor: aşağı inilir. Her hücreye yazılan sayı, girişten oraya en az adım sayısıdır.

01234566▸◂giriş: sol üstçıkış:sağ alt

Uzaklık 5'te yol çatallanır: dalga hem sağa hem aşağı yayılır. BFS "var olan tüm yolları eşzamanlı dener".

0123485678678▸◂giriş: sol üstçıkış:sağ alt

İki kol aynı anda ilerler: biri yukarıdaki odaya, biri aşağıya.

01210394856789610789▸◂giriş: sol üstçıkış:sağ alt

Uzaklık 10: dalga yukarıdaki koridora ve aşağıda alt koridora ulaştı.

0111122103948567896107891112▸◂giriş: sol üstçıkış:sağ alt

Alt koridor çıkışa yaklaşıyor; üst kol çıkmaz sokaklarda dolaşıyor.

0111121314210143948567896101478911121314▸◂giriş: sol üstçıkış:sağ alt

Çıkış hücresine 14 adımda ulaşıldı. BFS ilk ulaştığı anda bu uzaklık kesin olarak en kısadır.

0111121314210143948567896101478911121314▸◂giriş: sol üstçıkış:sağ alt

Ata (parent) bağlantıları çıkıştan geriye izlenerek en kısa yol (yeşil, 15 hücre, 14 adım) elde edilir. Kalan hücreler (uzaklık 15–17) bu yol için gereksizdi.

BFS

BFS Ağacı ve En Kısa Yol

düğüm12345678
uzaklık01111222
ata—1111223

"BFS Adım Adım" çizgesi, kaynak 1. Yol(8): 8 → ata 3 → ata 1, ters çevrilince 1 → 3 → 8 (2 kenar).

  • Keşifte: uzaklik[w] = uzaklik[v] + 1; ata[w] = v;
  • Kuyruktan çıkan uzaklıklar azalmayan sıradadır (0, 1, 1, 1, 1, 2, 2, 2); bu yüzden bir düğüme ilk ulaşan yol en kısadır.

Yolu geri kurma

List<Integer> yol(int[] ata, int s, int t) {
  LinkedList<Integer> yol = new LinkedList<>();
  for (int v = t; v != -1; v = ata[v])
    yol.addFirst(v);   // hedeften geriye
  if (yol.getFirst() != s)
    return null;       // t'ye ulaşılamadı
  return yol;
}
Yalnızca ağırlıksız (ya da tüm ağırlıkları eşit) çizgede geçerlidir. Ağırlıklı çizgede en kısa yol için Dijkstra (Bölüm 4.2) gerekir.

BFS

BFS ve DFS Karşılaştırması

DFSBFS
Yardımcı yapıYığın (LIFO) / özyinelemeKuyruk (FIFO)
Gezinme biçimibir dalı sonuna kadar, sonra geri dönüşkatman katman (uzaklık sırasıyla)
ZamanO(V + E) liste · O(V²) matrisO(V + E) liste · O(V²) matris
Ek bellekO(V): en uzun yol yığındaO(V): en geniş katman kuyrukta
En kısa yolhayırevet (ağırlıksız çizgede)
Ürettiği ağaçderin, ince DFS ağacısığ, geniş BFS ağacı
Tipik kullanımdöngü, bileşen, topolojik sıra, SCC, geri izlemeen az adım, seviye, iki parçalılık testi, yayılma
Aynı çizgede (izleme slaytlarındaki 8 düğümlü yönlü çizge, kaynak 0): DFS 0 1 2 3 5 6 4 7, BFS 0 1 2 7 3 4 5 6.

BFS

Deneyin: BFS ve DFS

Yönsüz çizge; komşular alfabetik sırayla gezilir. DFS özyinelemeli sürümün sırasını verir (yığına komşular ters sırada itilir). Sarı: kuyrukta / yığında · turuncu çerçeve: şu an işlenen · koyu: bitti.

Tarjan SCC

Güçlü Bağlantılı Bileşenler

  • Yönlü çizgede u ve v karşılıklı ulaşılabilir: u'dan v'ye ve v'den u'ya yol var.
  • Güçlü bağlantılı bileşen (strongly connected component, SCC): her düğümün diğer her düğüme ulaşabildiği maksimal düğüm kümesi.
  • Her düğüm tam bir SCC'ye aittir; tek düğüm de bir SCC olabilir ({8}).
  • Dikkat: "bir düğüm ve ondan erişilebilen tüm düğümler" SCC değildir: 8'den herkese ulaşılır ama kimse 8'e ulaşamaz.
  • Tarjan algoritması (1972) tüm SCC'leri tek bir DFS ile bulur.
13672458

SCC'ler: {1, 2, 3}, {4, 5}, {6, 7}, {8}

Her SCC tek düğüme indirgenirse elde edilen bileşen çizgesi döngüsüzdür (DAG): sosyal ağlarda topluluklar, derleyicilerde karşılıklı bağımlı modüller, 2-SAT çözümü.

Tarjan SCC

Tarjan: İlkeler ve Adımlar

  1. DFS tabanlıdır: çizgenin tüm düğümleri sırayla denenir; ziyaret edilmemiş her düğümden DFS başlatılır.
  2. DFS sırasında ziyaret edilen her düğüme bir indeks atanır: düğümün keşif sırası (1, 2, 3, …). Mevcut DFS yolundaki ve SCC'si henüz belirlenmemiş düğümler bir yığında tutulur.
  3. Her düğüm için enDüşükBağ (low-link) hesaplanır: düğümün DFS alt ağacından, en fazla bir kenarla hâlâ yığında olan düğümlere ulaşarak erişilebilen en küçük indeks.
    • Ağaç kenarı v → w: dönüşte enDüşükBağ(v) = min(enDüşükBağ(v), enDüşükBağ(w))
    • Yığındaki w'ye kenar: enDüşükBağ(v) = min(enDüşükBağ(v), indeks(w))
    • Bitmiş bir SCC'deki w'ye kenar: yok sayılır.
  4. v'nin işi bitince enDüşükBağ(v) = indeks(v) ise v bir SCC'nin köküdür: yığından v'ye kadar (v dahil) çekilen düğümler bir SCC oluşturur.
Sezgi: enDüşükBağ(v) < indeks(v) ise v'nin alt ağacından daha eski bir yığın düğümüne geri dönülebiliyordur; v o düğümle aynı SCC'dedir, kök değildir.

Tarjan SCC · Adım adım

Tarjan Adım Adım: indeks, enDüşükBağ

13672458yığınSCC'ler: —

Yönlü çizge, 8 düğüm. Her düğümün yanına indeks,enDüşükBağ yazılacak. Beyaz = ziyaret edilmedi, sarı = yığında, renkli = SCC'si belirlendi.

11,13672458yığın1SCC'ler: —

SCC(1): indeks = enDüşükBağ = 1; 1 yığına itilir.

11,136722,2458yığın12SCC'ler: —

SCC(2): indeks = enDüşükBağ = 2; 2 yığına itilir.

11,133,36722,2458yığın123SCC'ler: —

SCC(3): indeks = enDüşükBağ = 3; 3 yığına itilir.

11,133,16722,2458yığın123SCC'ler: —

Kenar 3 → 1: 1 yığında → enDüşükBağ(3) = min(3, indeks(1) = 1) = 1.

11,133,16722,1458yığın123SCC'ler: —

3 bitti; enDüşükBağ 1 < indeks 3 → kök değil, yığında kalır. 2'ye dönüldü: enDüşükBağ(2) = min(2, enDüşükBağ(3) = 1) = 1.

11,133,16722,1458yığınSCC'ler: {1, 2, 3}

2 bitti; enDüşükBağ 1 < indeks 2 → kök değil, yığında kalır. 1'e dönüldü; enDüşükBağ(1) = 1 değişmedi. 1'de enDüşükBağ = indeks = 1 → 1 köktür: yığından 1'e kadar çekilenler bir SCC: {1, 2, 3}.

11,133,16722,144,458yığın4SCC'ler: {1, 2, 3}

SCC(4): indeks = enDüşükBağ = 4; 4 yığına itilir.

11,133,16722,144,455,58yığın45SCC'ler: {1, 2, 3}

4 → 2 yok sayılır (2 bitmiş bir SCC'de, yığında değil). 4 → 3 yok sayılır (3 bitmiş bir SCC'de, yığında değil). SCC(5): indeks = enDüşükBağ = 5; 5 yığına itilir.

11,133,166,6722,144,455,58yığın456SCC'ler: {1, 2, 3}

SCC(6): indeks = enDüşükBağ = 6; 6 yığına itilir.

11,133,166,677,722,144,455,58yığın4567SCC'ler: {1, 2, 3}

6 → 3 yok sayılır (3 bitmiş bir SCC'de, yığında değil). SCC(7): indeks = enDüşükBağ = 7; 7 yığına itilir.

11,133,166,677,622,144,455,58yığın4567SCC'ler: {1, 2, 3}

Kenar 7 → 6: 6 yığında → enDüşükBağ(7) = min(7, indeks(6) = 6) = 6.

11,133,166,677,622,144,455,58yığın45SCC'ler: {1, 2, 3} · {6, 7}

7 bitti; enDüşükBağ 6 < indeks 7 → kök değil, yığında kalır. 6'ya dönüldü; enDüşükBağ(6) = 6 değişmedi. 6'da enDüşükBağ = indeks = 6 → 6 köktür: yığından 6'ya kadar çekilenler bir SCC: {6, 7}.

11,133,166,677,622,144,455,48yığın45SCC'ler: {1, 2, 3} · {6, 7}

5'e dönüldü; enDüşükBağ(5) = 5 değişmedi. Kenar 5 → 4: 4 yığında → enDüşükBağ(5) = min(5, indeks(4) = 4) = 4.

11,133,166,677,622,144,455,48yığınSCC'ler: {1, 2, 3} · {6, 7} · {4, 5}

5 bitti; enDüşükBağ 4 < indeks 5 → kök değil, yığında kalır. 4'e dönüldü; enDüşükBağ(4) = 4 değişmedi. 4'te enDüşükBağ = indeks = 4 → 4 köktür: yığından 4'e kadar çekilenler bir SCC: {4, 5}.

11,133,166,677,622,144,455,488,8yığın8SCC'ler: {1, 2, 3} · {6, 7} · {4, 5}

SCC(8): indeks = enDüşükBağ = 8; 8 yığına itilir.

11,133,166,677,622,144,455,488,8yığın8SCC'ler: {1, 2, 3} · {6, 7} · {4, 5}

8 → 5 yok sayılır (5 bitmiş bir SCC'de, yığında değil). 8 → 7 yok sayılır (7 bitmiş bir SCC'de, yığında değil). Öz döngü 8 → 8: 8 yığında ama enDüşükBağ = min(8, 8) = 8 değişmez.

11,133,166,677,622,144,455,488,8yığınSCC'ler: {1, 2, 3} · {6, 7} · {4, 5} · {8}

8'de enDüşükBağ = indeks = 8 → 8 köktür: yığından 8'e kadar çekilenler bir SCC: {8}.

11,133,166,677,622,144,455,488,8yığın boşSCC'ler: {1, 2, 3} · {6, 7} · {4, 5} · {8}

Sonuç: 4 SCC. Her SCC, kökü (indeks = enDüşükBağ olan düğüm: 1, 6, 4, 8) bittiği anda bulundu; bulunma sırası ters topolojik sıradır.

Tarjan SCC

Tarjan: Sözde Kod

TARJAN_SCC(G):
  indeks = 1
  yığın = [ ]
  SCCler = [ ]
  her bir v için V içinde:
    eğer v.indeks tanımlı değilse:
      SCC(v)
  döndür SCCler
SCC(v):
  v.indeks = v.enDüşükBağ = indeks++
  yığın.ekle(v)
  her bir (v, w) için E içinde:
    eğer w.indeks tanımlı değilse:
      SCC(w)
      v.enDüşükBağ = min(v.enDüşükBağ, w.enDüşükBağ)
    değilse eğer w yığında ise:
      v.enDüşükBağ = min(v.enDüşükBağ, w.indeks)
  eğer v.enDüşükBağ == v.indeks:
    scc = [ ]
    döngü w ≠ v olduğu sürece:  // en az bir kez
      w = yığın.çıkar()
      scc.ekle(w)
    SCCler.ekle(scc)
  • Görselde indeks 1'den başlatıldı (indeks = 1); 0'dan başlatmak da aynı SCC'leri verir.
  • "yığında mı?" sorusu, yığına paralel bir yiginda[] dizisiyle O(1) zamanda yanıtlanır.

Tarjan SCC · Kodu adım adım çalıştır

Tarjan: scc(0) İzleme

01,11234yığın0

Çizge: 0→1, 1→2, 2→0, 2→3, 3→4, 4→3; indeks[w] == 0 = ziyaret edilmedi. scc(0): indeks ve dusuk = 1; 0 yığına itilir.

01,11234yığın0

0 → 1: 1 ziyaret edilmemiş → özyinelemeli çağrı.

01,112,2234yığın01

scc(1): indeks ve dusuk = 2; 1 yığına itilir.

01,112,2234yığın01

1 → 2: 2 ziyaret edilmemiş → özyinelemeli çağrı.

01,112,223,334yığın012

scc(2): indeks ve dusuk = 3; 2 yığına itilir.

01,112,223,134yığın012

2 → 0: 0 yığında (geri kenar) → dusuk[2] = min(3, indeks[0] = 1) = 1.

01,112,223,134yığın012

2 → 3: 3 ziyaret edilmemiş → özyinelemeli çağrı.

01,112,223,134,44yığın0123

scc(3): indeks ve dusuk = 4; 3 yığına itilir.

01,112,223,134,44yığın0123

3 → 4: 4 ziyaret edilmemiş → özyinelemeli çağrı.

01,112,223,134,445,5yığın01234

scc(4): indeks ve dusuk = 5; 4 yığına itilir.

01,112,223,134,445,4yığın01234

4 → 3: 3 yığında (geri kenar) → dusuk[4] = min(5, indeks[3] = 4) = 4.

01,112,223,134,445,4yığın01234

dusuk[4] = 4 ≠ indeks[4] = 5 → 4 kök değil, yığında kalır; çağrı döner.

01,112,223,134,445,4yığın01234

scc(4) döndü: dusuk[3] = min(4, dusuk[4] = 4) = 4.

01,112,223,134,445,4yığın012

dusuk[3] == indeks[3] = 4 → 3 köktür; 4, 3 çekilip yazdırılır: SCC {3, 4}.

01,112,223,134,445,4yığın012

scc(3) döndü: dusuk[2] = min(1, dusuk[3] = 4) = 1.

01,112,223,134,445,4yığın012

dusuk[2] = 1 ≠ indeks[2] = 3 → 2 kök değil, yığında kalır; çağrı döner.

01,112,123,134,445,4yığın012

scc(2) döndü: dusuk[1] = min(2, dusuk[2] = 1) = 1.

01,112,123,134,445,4yığın012

dusuk[1] = 1 ≠ indeks[1] = 2 → 1 kök değil, yığında kalır; çağrı döner.

01,112,123,134,445,4yığın012

scc(1) döndü: dusuk[0] = min(1, dusuk[1] = 1) = 1.

01,112,123,134,445,4yığın

dusuk[0] == indeks[0] = 1 → 0 köktür; 2, 1, 0 çekilip yazdırılır: SCC {0, 1, 2}.

void scc(int v) {
  indeks[v] = dusuk[v] = ++sayac;
  yigin.push(v); yiginda[v] = true;
  for (int w : komsu[v]) {
    if (indeks[w] == 0) {
      scc(w);
      dusuk[v] = Math.min(dusuk[v], dusuk[w]);
    } else if (yiginda[w])
      dusuk[v] = Math.min(dusuk[v], indeks[w]);
  }
  if (dusuk[v] == indeks[v]) {
    int w;
    do {
      w = yigin.pop(); yiginda[w] = false;
      System.out.print(w + " ");
    } while (w != v);
    System.out.println();
  }
}

Tarjan SCC

Karmaşıklık ve Kosaraju

Tarjan'ın karmaşıklığı: O(V + E)

  • V düğüm sayısı, E kenar sayısı.
  • Her düğüm bir kez ziyaret edilir, yığına bir kez itilip bir kez çekilir: O(V).
  • Her kenar bir kez incelenir: O(E).
  • Ek bellek: indeks, enDüşükBağ, yiginda dizileri ve yığın: O(V).

Kosaraju algoritması

  1. DFS ile düğümleri bitiş sırasına göre yığına it.
  2. Çizgenin tersini (transpose) oluştur.
  3. Yığından çekilen sırayla ters çizgede DFS; her DFS ağacı bir SCC.

"Tarjan Adım Adım" çizgesinde Kosaraju da aynı dört SCC'yi bulur: {1, 2, 3}, {4, 5}, {6, 7}, {8}.

TarjanKosaraju
DFS sayısı12 (biri ters çizgede)
Ek yapıindeks / enDüşükBağ, yığınters çizge (O(V + E) bellek)
ZamanO(V + E)O(V + E)

Uygulamalar

Topolojik Sıralama

01273456

Giriş dereceleri: 0:0, 1:1, 2:2, 3:1, 4:1, 5:1, 6:2, 7:1

  • Döngüsüz yönlü çizgede (DAG) her u → v kenarı için u'nun v'den önce geldiği sıralama: ön koşullu dersler, derleme sırası, görev planlama.
  • Kahn (BFS tabanlı): giriş derecesi 0 olanları kuyruğa koy; çıkarılan düğümün kenarlarını sil, derecesi 0'a düşeni kuyruğa ekle.
  • DFS tabanlı: düğümleri bitiş sırasına göre listele, listeyi ters çevir.
Kahn0 1 7 2 3 4 5 6
DFS (ters bitiş)0 7 1 2 4 3 5 6
İkisi de geçerli: topolojik sıra tek değildir. Çıkarılan düğüm sayısı V'den azsa çizgede döngü vardır (DFS örneğindeki 2 → 0 kenarı eklenirse sıralama yapılamaz). Zaman O(V + E).

Uygulamalar

Gezinmenin Diğer Kullanımları

Bağlı bileşenlerZiyaret edilmemiş her düğümden yeni bir DFS/BFS başlat; başlatma sayısı = bileşen sayısı.
İki parçalılık testiBFS ile katmanları iki renge boya; aynı renkli iki komşu varsa tek uzunlukta döngü vardır, çizge iki parçalı değildir.
Döngü tespitiYönsüz: ata olmayan ziyaretli komşu. Yönlü: yığındaki (sarı) düğüme giden geri kenar.
Köprü ve eklem noktasıTarjan'ın enDüşükBağ fikri: enDüşükBağ(w) > keşif(v) ise v–w köprüdür.
Yinelemeli derinleştirme (IDDFS)Derinlik sınırı 0, 1, 2… artan DFS'ler: DFS'in belleği, BFS'in sığ çözüm garantisi.
Rastgele yürüyüşHer adımda rastgele bir komşuya geçiş; PageRank ve büyük ağlardan örnekleme.

Özet

Özet

KonuHatırlanacaklar
Gösterimliste O(V + E) bellek, matris O(V²); gezinme listeyle O(V + E), matrisle O(V²)
DFSyığın / özyineleme; derine in, geri dön; ziyaret dizisi döngüye karşı şart
Yığınla DFSçekerken işaretle; bir düğüm birden çok kez itilebilir; sıra komşu sırasının tersi
BFSkuyruk; eklerken işaretle; katman katman; ata dizisiyle ağırlıksız en kısa yol
Labirenthücre = düğüm; BFS tüm yolları eşzamanlı dener, çıkışa ilk ulaştığında yol en kısadır
SCCkarşılıklı ulaşılabilir maksimal küme; bileşen çizgesi DAG'dir
Tarjanindeks = keşif sırası; enDüşükBağ; enDüşükBağ = indeks → kök, yığından SCC çek; O(V + E)
Uygulamalartopolojik sıra (Kahn / ters bitiş), bileşenler, iki parçalılık, döngü, köprü

Özet

Etkileşimli Simülatörler

Çizge Gezinme Simülatörüİstediğiniz sayıda düğümle rastgele yönsüz bir çizge üretin, düğümleri sürükleyin ve BFS ile DFS'in çizgeyi adım adım nasıl gezdiğini izleyin.
Çizge Yapısı AlgoritmalarıKüçük örnek çizgelerde topolojik sıralama (Kahn), güçlü bağlantılı bileşenler (Kosaraju) ve eklem noktalarını tek tıkla görün.
İki Parçalılık, Döngü ve KöprüAynı yönsüz çizgeyi üç açıdan inceleyin: BFS ile iki renge boyama, DFS ile döngü tespiti ve köprü kenarlarının bulunması.

Özet

Sık Yapılan Hatalar

Ziyaret dizisini unutmakDöngülü çizgede DFS sonsuz özyinelemeye, BFS sonsuz kuyruğa girer. "BFS döngülü çizgede çalışmaz" sanısının kaynağı budur; işaretlemeyle sorunsuz çalışır.
BFS'te çıkarırken işaretlemekAynı düğüm birçok komşudan kuyruğa eklenir; sonuç yine doğru olabilir ama kuyruk O(E)'ye büyür. Eklerken işaretleyin.
DFS'ten en kısa yol beklemekDFS'in hedefe ilk ulaştığı yol en kısa değildir. Ağırlıksızda BFS, ağırlıklıda Dijkstra kullanın.
Yığınla DFS'in sırasıKomşular sırayla itilince sıra ters çıkar (0 7 2 … ≠ 0 1 2 …). Özyinelemeli sırayı isteyen ters sırada itmelidir.
Tarjan'da "yığında mı?" denetimini atlamakYalnızca yığındaki w için min(…, indeks(w)) yapılır; SCC'si bulunmuş w yok sayılır. Aksi hâlde kökler kaybolur.
Bağlı olmayan çizgeTek bir kaynaktan gezinme yalnızca o bileşeni görür. Tüm çizge için her ziyaret edilmemiş düğümden yeniden başlatın.

Özet

Örnek Problemler

Yönsüz çizge, komşular alfabetik: A–B, A–C, B–D, C–D, C–E, D–F, E–F, F–G.

  1. A'dan BFS ziyaret sırasını ve her düğümün uzaklığını yazın.
  2. A'dan özyinelemeli DFS ziyaret sırası nedir?
  3. A'dan G'ye en kısa yol (BFS ata dizisiyle) nedir?
  4. Çizge iki parçalı mıdır? Kümeleri verin.
  5. Yönlü çizge 0→1, 1→2, 2→0, 1→3, 3→4, 4→5, 5→3, 5→6: Tarjan (0'dan, indeks 1'den) ile SCC'leri bulunma sırasıyla yazın.
  6. A→C, B→C, B→D, C→E, D→E, E→F için Kahn sırası (kuyruk alfabetik başlar)?
Cevapları göster
  1. A B C D E F G; uzaklıklar A0, B1, C1, D2, E2, F3, G4.
  2. A → B → D → C → E → F → G: A B D C E F G.
  3. Ata: G←F, F←D, D←B, B←A → A–B–D–F–G (4 kenar).
  4. Evet: {A, D, E, G} ve {B, C, F}; tüm döngüler (A-B-D-C, C-D-F-E) çift uzunlukta.
  5. {6} (6: 7,7), {3, 4, 5} (indeks 4, 5, 6; enDüşükBağ 4), {0, 1, 2} (enDüşükBağ 1).
  6. Kuyruk [A, B] → A B C D E F.

Özet

Alıştırmalar

  1. Örnek problemlerdeki çizgede A'dan yığınla DFS (komşular alfabetik itilir) sırası nedir? Toplam kaç itme yapılır?
  2. V = 1000, E = 3000 olan bir çizgede BFS'in komşuluk listesi ve matris ile yaklaşık iş miktarını karşılaştırın.
  3. BFS'in ağırlıklı çizgede en kısa yolu bulamadığını gösteren küçük bir örnek verin.
  4. Bir yönsüz çizgenin bağlı bileşen sayısını bulan algoritmayı tarif edin; karmaşıklığı nedir?
  5. Tarjan'da "bitmiş SCC'deki w" için min(v.enDüşükBağ, w.indeks) yapılsaydı "Tarjan Adım Adım" örneğinde ne olurdu?
Cevapları göster
  1. A C E F G D B; her düğüm bir kez işlenir ve 2E = 16 komşu itilir, başlangıçla 17 itme.
  2. Liste: V + 2E ≈ 1000 + 6000 = 7000 işlem. Matris: V² = 1 000 000 hücre: ≈ 140 kat fazla.
  3. s→t (ağırlık 10), s→a (1), a→t (1): BFS t'ye 1 kenarla (maliyet 10) ulaşır; en ucuz yol s→a→t (maliyet 2).
  4. Sayaç = 0; her v için ziyaret edilmemişse sayaç++ ve v'den DFS/BFS. O(V + E).
  5. 4 → 2 kenarı enDüşükBağ(4)'ü 2'ye, 6 → 3 kenarı enDüşükBağ(6)'yı 3'e, 8 → 5 kenarı enDüşükBağ(8)'i 5'e indirir: 4, 6 ve 8 kök sayılmaz; {4, 5}, {6, 7}, {8} hiç çıkarılmaz, 4–8 yığında kalır.

Özet

Kaynaklar

  • Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, MIT Press, 2022 (Bölüm 20: Elementary Graph Algorithms).
  • Sedgewick ve Wayne, Algorithms, 4. baskı, Addison-Wesley, 2011 (Bölüm 4.1–4.2).
  • R. E. Tarjan, "Depth-First Search and Linear Graph Algorithms", SIAM Journal on Computing 1(2), 1972.
  • A. B. Kahn, "Topological Sorting of Large Networks", Communications of the ACM 5(11), 1962.
  • Kleinberg ve Tardos, Algorithm Design, Pearson, 2006 (Bölüm 3: Graphs).

Son

Bölüm 4.1: Çizge Gezinme Algoritmaları
Sonraki bölüm: Bölüm 4.2: En Kısa Yol Algoritmaları
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.