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

Bölüm 4.1: Çizge Gezinme Algoritmaları · Çalışma Soruları
Çizge gösterimiDerinlik öncelikli arama (DFS)Genişlik öncelikli arama (BFS)Ağırlıksız en kısa yolTarjan SCCTopolojik sıralama
Sercan KÜLCÜ

Çoktan Seçmeli · Gösterim

Soru 1: Liste ve Matris Boyutu

Yönsüz, 7 düğümlü ve 9 kenarlı bir çizge komşuluk listesi ve komşuluk matrisiyle ayrı ayrı tutuluyor. Komşuluk listelerindeki toplam öğe sayısı ve matrisin hücre sayısı nedir?

C: Yönsüz çizgede her kenar iki listede görünür: 2E = 18 öğe; matris V × V = 49 hücredir. A, yönsüz kenarın iki kez yazıldığını unutur; B köşegeni (n(n−1)) dışarıda bırakır. Bellek: liste O(V + E), matris O(V²).

Çoktan Seçmeli · Gösterim

Soru 2: Seyrek Çizgede BFS İşi

V = 1000 düğümlü, E = 4000 kenarlı yönsüz bir çizgede BFS'in yaptığı iş komşuluk listesi ve komşuluk matrisi için yaklaşık olarak kaçtır?

B: Listede her düğüm bir kez işlenir ve listelerin toplam uzunluğu 2E'dir: V + 2E = 1000 + 8000 = 9000. Matriste her düğüm için V öğeli satır taranır: V² = 10⁶, yani yaklaşık 110 kat fazla iş. A yönsüz kenarın iki listede yer aldığını unutur; C matrisi E² sanar.

Klasik Soru · Gösterim

Soru 3: BFS Kodunun Karmaşıklığı

(a) Aşağıdaki kodun zaman ve bellek karmaşıklığı nedir? (b) Komşuluk listesi yerine komşuluk matrisi kullanılsaydı ne değişirdi? (c) Kuyruk yerine, öğeleri baştan silerken kaydıran bir dizi (ArrayList.remove(0)) kullanılsaydı ne olurdu?

void bfs(int baslangic, List<List<Integer>> komsuluk,
         int dugumSayisi) {
  Queue<Integer> kuyruk = new LinkedList<>();
  boolean[] ziyaretEdildi = new boolean[dugumSayisi];
  ziyaretEdildi[baslangic] = true;
  kuyruk.add(baslangic);
  while (!kuyruk.isEmpty()) {
    int u = kuyruk.poll();
    System.out.print(u + " ");
    for (int v : komsuluk.get(u))
      if (!ziyaretEdildi[v]) {
        ziyaretEdildi[v] = true;
        kuyruk.add(v);
      }
  }
}
Cevabı göster
  • (a) Her düğüm kuyruğa en çok bir kez girer ve çıkar: O(V); her komşu listesi bir kez taranır: O(E). Zaman O(V + E); bellek liste O(V + E) + kuyruk ve ziyaretEdildi O(V).
  • (b) Bir düğümün komşularını bulmak için V öğeli satır taranır: zaman O(V²), bellek O(V²). Yoğun çizgede (E ≈ V²) fark kalmaz, seyrek çizgede matris çok kötüdür.
  • (c) Baştan silme kalan öğeleri kaydırır: tek poll O(V) olabilir, V çıkarma en kötü O(V²). Bellek değişmez (O(V)). Sıra ve sonuç aynıdır; yalnızca süre bozulur. Çare: baş indisi tutmak ya da dairesel dizi.

Çıktı Sorusu · Gösterim

Soru 4: Matrisle DFS

Yönlü çizge komşuluk matrisiyle verilmiştir (G[i][j] = 1: i → j kenarı). dfs(0) ne yazdırır?

01234
000101
110000
201010
301000
400010
void dfs(int v) {
  ziyaret[v] = true;
  System.out.print(v + " ");
  for (int w = 0; w < n; w++)
    if (G[v][w] == 1 && !ziyaret[w])
      dfs(w);
}
Cevabı göster

Çıktı: 0 2 1 3 4

  • 0'ın satırı: ilk 1 sütun 2'de → dfs(2). 2'nin satırı: 1 → dfs(1); 1'in tek komşusu 0 ziyaretli, döner.
  • 2'de taramaya devam: 3 → dfs(3); 3 → 1 ziyaretli, döner. 2 biter, 0'a dönülür.
  • 0'da sütun 4 → dfs(4); 4 → 3 ziyaretli. Çağrılar biter.

Satırlar soldan sağa tarandığı için komşular artan sırada denenir. Her düğüm için n öğeli satır tarandığından zaman O(V²) (BFS sırası ise 0 2 4 1 3 olurdu).

Adım Adım Çalıştırma · DFS

Soru 5: Özyinelemeli DFS İzleme

dfs(0, ziyaret) hangi sırayla yazdırır? Sarı düğümler çağrı yığınındaki çerçevelerdir.

012345

Yönlü çizge, komşu listeleri artan sırada: 0: 1, 3 · 1: 2, 4 · 2: 0 · 3: 4 · 4: 2, 5 · 5: —. Hiçbir düğüm ziyaret edilmedi.

012345

dfs(0): 0 işaretlenir ve yazdırılır; çağrı yığınında tek çerçeve var.

012345

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

012345

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

012345

2 → 0 kenarı: 0 zaten ziyaretli (yığında (işi sürüyor)) → atlanır.

012345

2 bitti, çağrı döner; kontrol 1'e geri gelir (geri dönüş).

012345

1'in komşusu 4 ziyaret edilmemiş → dfs(4): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.

012345

4 → 2 kenarı: 2 zaten ziyaretli (bitmiş) → atlanır.

012345

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

012345

5, 4, 1 bitti, çağrı döner; kontrol 0'a geri gelir (geri dönüş).

012345

0'ın komşusu 3 ziyaret edilmemiş → dfs(3): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.

012345

3 → 4 kenarı: 4 zaten ziyaretli (bitmiş) → atlanır.

012345

3 bitti, çağrı döner; kontrol 0'a geri gelir (geri dönüş).

012345

Tüm çağrılar döndü. Çıktı: 0 1 2 4 5 3. Vurgulu kenarlar DFS ağacıdır; 2 → 0 geri kenardır (döngü).

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

Adım Adım Çalıştırma · DFS

Soru 6: Yığınla DFS İzleme

Önceki sorudaki çizgede dfsYigin(0) ne yazdırır? Yığının içeriğini izleyin.

012345yığın0← üst

Aynı çizge. Başlangıç düğümü 0 yığına itildi; henüz hiçbir düğüm işaretli değil.

012345yığın13← üst

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

012345yığın14← üst

3 çekildi: işaretlenir, yazdırılır; komşusu 4 itilir.

012345yığın125← üst

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

012345yığın12← üst

5 çekildi: işaretlenir, yazdırılır; komşusu yok.

012345yığın10← üst

2 çekildi: işaretlenir, yazdırılır; komşusu 0 itilir.

012345yığın1← üst

0 çekildi ama zaten ziyaretli → atlanır. Bir düğüm yığına birden çok kez girebilir.

012345yığın24← üst

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

012345yığın2← üst

4 çekildi ama zaten ziyaretli → atlanır. Bir düğüm yığına birden çok kez girebilir.

012345yığınboş

2 çekildi ama zaten ziyaretli → atlanır. Bir düğüm yığına birden çok kez girebilir.

012345yığınboş

Yığın boş, döngü biter. Çıktı 0 3 4 5 2 1; özyinelemeli sürümün sırasından (0 1 2 4 5 3) farklıdır, çünkü en son itilen komşu önce çı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);
    }
  }
}

Çoktan Seçmeli · DFS

Soru 7: Yığınla DFS Sırası

Yönsüz çizgede komşu listeleri artan sıradadır. dfsYigin(0) (çekerken işaretle, komşuları listedeki sırayla it) ne yazdırır?

012345

C: 0 çekilince 1 ve 4 itilir, üstte 4 vardır; 4'ten 0, 3, 5 itilir ve 5 önce çıkar… A (0 1 2 3 4 5) özyinelemeli DFS'in sırasıdır; yığınla aynı sırayı elde etmek için komşular ters sırada itilmelidir. B ise BFS sırasıdır.

Çoktan Seçmeli · DFS

Soru 8: Yığınla DFS'in Özellikleri

Derste yazılan dfsYigin (yığından çekerken işaretleyen sürüm) için aşağıdakilerden hangisi doğrudur?

B: İşaretleme çekerken yapıldığı için henüz çekilmemiş bir düğüm farklı komşulardan tekrar itilebilir; itme sayısı 1 + Σ derece, yani O(E)'dir. C yanlıştır: sıra itme sırasının tersine döner. D yanlıştır: ziyaret dizisi olmadan döngüde aynı düğümler sonsuza kadar itilir.

Çoktan Seçmeli · DFS

Soru 9: Yönlü Çizgede Döngü

Yönlü bir çizgede DFS ile döngü aranıyor (sarı: çağrı yığınında, koyu: bitmiş, beyaz: keşfedilmemiş). DFS sırasında hangi durum kesin olarak bir döngü olduğunu gösterir?

abcde

C: Yığındaki w, v'nin atasıdır; w ⇝ v ağaç yolu ve v → w kenarı birlikte döngüdür (geri kenar). A ve B yanlıştır: yönlü çizgede bitmiş düğüme giden kenar (çapraz/ileri kenar) döngü oluşturmayabilir. Şekilde d → b kenarı daha sonra incelenecek; b yığında olduğundan e → d → b → c → e döngüsü bulunur.

Çıktı Sorusu · DFS

Soru 10: Kaç Kez İtilir?

Yönsüz çizgede komşu listeleri artan sıradadır. Önceki sorulardaki dfsYigin(0) çalıştırılıyor. (a) Çıktı nedir? (b) push toplam kaç kez çağrılır? (c) Yığın en çok kaç öğe tutar?

012345
Cevabı göster

(a) 0 2 5 4 3 1

(b) 15 itme: başlangıçta 1, sonra her düğüm bir kez işlenir ve tüm komşularını iter. Komşu listelerinin toplamı 2E = 14 → 1 + 2E = 15.

(c) En çok 7 öğe: bazı düğümler yığında birden çok kopyayla bekler (çekerken işaretleme). Özyinelemeli DFS'te ise yığın en uzun yol kadardır, O(V).

Çıktı Sorusu · DFS

Soru 11: Kaç Kez Başlatılır?

Yönlü çizgede aşağıdaki kod çalıştırılıyor (dfs özyinelemeli DFS'tir). Ne yazdırır? Döngü v = n − 1'den 0'a doğru dönseydi ne yazdırırdı?

320154
int sayac = 0;
for (int v = 0; v < n; v++)
  if (!ziyaret[v]) {
    dfs(v, ziyaret);
    sayac++;
  }
System.out.println(sayac);
Cevabı göster

Artan sırada: 5. dfs(0) yalnızca {0, 1}'i gezer (0'dan 2'ye kenar yok); sonra 2, 3, 4, 5 ayrı ayrı başlatılır.

Azalan sırada: 2. dfs(5) {5, 4}'ü, dfs(3) ise 3 → 2 → 0 → 1 ile kalan dört düğümü gezer.

Yönsüz çizgede başlatma sayısı bağlı bileşen sayısına eşittir. Yönlü çizgede ise sıraya bağlıdır; ne zayıf bileşen sayısını (2) ne de güçlü bağlantılı bileşen sayısını (6) verir.

Adım Adım Çalıştırma · BFS

Soru 12: BFS İzleme

bfs(0) hangi sırayla yazdırır? Kuyruğun içeriğini ve BFS ağacını izleyin.

0351624kuyruk0↑ ön

Yönsüz çizge, komşu listeleri artan sırada. 0 işaretlendi ve kuyruğa kondu (katman 0).

0351624kuyruk35↑ ön

0 çıkarıldı ve yazdırıldı. Yeni komşular 3, 5 işaretlenip kuyruğun sonuna eklendi (uzaklık 1).

0351624kuyruk516↑ ön

3 çıkarıldı ve yazdırıldı. Yeni komşular 1, 6 işaretlenip kuyruğun sonuna eklendi (uzaklık 2).

0351624kuyruk162↑ ön

5 çıkarıldı ve yazdırıldı. Yeni komşular 2 işaretlenip kuyruğun sonuna eklendi (uzaklık 2).

0351624kuyruk62↑ ön

1 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.

0351624kuyruk24↑ ön

6 çıkarıldı ve yazdırıldı. Yeni komşular 4 işaretlenip kuyruğun sonuna eklendi (uzaklık 3).

0351624kuyruk4↑ ön

2 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.

0351624kuyrukboş

4 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.

0351624kuyrukboş

Kuyruk boş. Çıktı 0 3 5 1 6 2 4; katmanlar {0}, {3, 5}, {1, 6, 2}, {4}. Vurgulu 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);
      }
  }
}

Çıktı Sorusu · BFS

Soru 13: BFS Uzaklıkları ve Yol

A'dan BFS (komşular alfabetik) ile ziyaret sırasını, her düğümün uzaklığını ve ebeveynini bulun. Ebeveyn dizisiyle A'dan H'ye en kısa yol nedir?

ABDCEGFH
Cevabı göster

Sıra: A B D C E G F H

düğümABCDEFGH
uzaklık01212323
ebeveyn—ABABCDG

H → ebeveyn G → ebeveyn D → ebeveyn A; ters çevrilince A → D → G → H (3 kenar). A–B–C–F–H de bir yoldur ama 4 kenarlıdır; BFS bir düğüme ilk ulaştığı anda en az kenarlı yolu bulmuştur.

Çıktı Sorusu · BFS

Soru 14: Çıkarırken İşaretlemek

BFS, düğümleri kuyruğa eklerken değil çıkarırken işaretleyecek biçimde değiştirildi. BFS izleme sorusundaki çizgede (kaynak 0) çıktı ne olur? add kaç kez çağrılır? Dersteki sürümde kaç kez çağrılıyordu?

kuyruk.add(s);
while (!kuyruk.isEmpty()) {
  int v = kuyruk.poll();
  if (ziyaret[v]) continue;
  ziyaret[v] = true;          // çıkarırken
  System.out.print(v + " ");
  for (int w : komsu[v])
    if (!ziyaret[w]) kuyruk.add(w);
}
Cevabı göster

Çıktı: 0 3 5 1 6 2 4 (sıra değişmez).

add: 9 kez; dersteki sürümde 7 kez (her düğüm bir kez).

Bir düğüm ilk keşfinde, dersteki sürümle aynı anda kuyruğa girer; bu yüzden sıra aynıdır. Ama işaretlenmeden önce başka komşulardan da eklenir: örneğin 6 hem 3'ten hem 5'ten, 4 hem 6'dan hem 2'den eklenir. Fazla kopyalar continue ile atlanır. Kuyruk O(V) yerine O(E)'ye büyüyebilir; bu yüzden eklerken işaretlenir.

Çoktan Seçmeli · BFS

Soru 15: Doğru mu Yanlış mı?

Aşağıdaki ifadelerden hangisi yanlıştır?

D yanlıştır: DFS bir dalı sonuna kadar izler; hedefe ilk ulaştığı yol uzun bir dolambaç olabilir. En az kenarlı yol için BFS, ağırlıklı çizgede Dijkstra gerekir. A, B, C doğrudur.

Çoktan Seçmeli · BFS

Soru 16: Ağırlıklı Çizgede BFS

BFS ebeveyn dizisiyle s'den t'ye bir yol bulunuyor (komşular alfabetik). Bulunan yolun toplam ağırlığı ve gerçek en kısa yolun ağırlığı nedir?

sabt22715

D: BFS kenar sayısına bakar; t'yi s'nin komşusu olarak ilk katmanda bulur: s → t (1 kenar, ağırlık 7). En hafif yol s → a → t = 2 + 2 = 4'tür. B, s → b → t'yi (6) en kısa sanar. Ağırlıklı çizgede Dijkstra gerekir; BFS yalnızca tüm ağırlıklar eşitse doğrudur.

Çoktan Seçmeli · BFS

Soru 17: Kuyruk ve Yığın Boyutu

15 düğümlü tam ikili ağaç (4 seviye) bir çizge olarak kökten geziliyor. Derste yazılan BFS'te kuyruk en çok kaç düğüm tutar, özyinelemeli DFS'te çağrı yığını en çok kaç çerçeve olur?

B: BFS son seviyedeki 8 yaprağı birlikte kuyrukta tutar (en geniş katman); DFS ise kökten yaprağa en uzun yol kadar, 4 çerçeve derinleşir. A ikisini karıştırır. Genel olarak BFS'in belleği en geniş katmana, DFS'inki en derin yola bağlıdır; ikisi de en kötü O(V).

Klasik Soru · BFS

Soru 18: İki Parçalılık Testi

A'dan BFS ile katmanları bulup çift katmanları bir renge, tek katmanları öteki renge boyayın. Çizge iki parçalı mıdır? Değilse sorunu hangi kenar gösterir ve D–E kenarı silinirse ne olur?

ABCDEF
Cevabı göster ABCDEFk0k1k1k2k2k3

Katmanlar: A (0); B, C (1); D, E (2); F (3). D–E kenarının iki ucu da katman 2'de → aynı renk: çizge iki parçalı değildir. C–D–E tek uzunlukta (3) bir döngüdür.

D–E silinirse tüm kenarlar ardışık katmanları bağlar: kümeler {A, D, E} ve {B, C, F}; çizge iki parçalı olur. Test O(V + E) sürer.

Çoktan Seçmeli · BFS

Soru 19: BFS mi, DFS mi?

Aşağıdaki problemlerden hangisi için DFS yerine BFS kullanılmalıdır?

A: BFS düğümleri uzaklık sırasıyla keşfeder; çıkışa ilk ulaştığında yol en kısadır. B (ters bitiş sırası), C (Tarjan) ve D (geri kenarla döngü tespiti) DFS'in derinlik ve bitiş bilgisine dayanır.

Çoktan Seçmeli · Tarjan SCC

Soru 20: Kaç SCC Var?

Yönlü çizgenin kaç güçlü bağlantılı bileşeni (SCC) vardır?

01263457

D: {0, 1, 2} (0 → 1 → 2 → 0), {3, 4} (3 ⇄ 4) ve {5, 6, 7} (5 → 6 → 7 → 5). 1 → 6 ve 2 → 3, 4 → 5 kenarları bileşenleri birbirine bağlar ama geri dönüş yolu olmadığı için onları birleştirmez. 1 cevabı, "0'dan herkese ulaşılıyor" yanılgısıdır: SCC karşılıklı ulaşılabilirlik ister.

Adım Adım Çalıştırma · Tarjan SCC

Soru 21: Tarjan İzleme

scc(0) çağrısı ne yazdırır? indeks, dusuk ve yığını izleyin.

01234

Çizge: 0 ⇄ 1, 1 → 2, 2 → 3 → 4 → 2. indeks[w] == 0 ziyaret edilmedi demektir; düğüm yanındaki etiket indeks/dusuk.

012341/1

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

012341/12/2

0 → 1: 1 ziyaret edilmemiş → scc(1): indeks = dusuk = 2; yığına itilir.

012341/12/1

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

012341/12/13/3

1 → 2: 2 ziyaret edilmemiş → scc(2): indeks = dusuk = 3; yığına itilir.

012341/12/13/34/4

2 → 3: 3 ziyaret edilmemiş → scc(3): indeks = dusuk = 4; yığına itilir.

012341/12/13/34/45/5

3 → 4: 4 ziyaret edilmemiş → scc(4): indeks = dusuk = 5; yığına itilir.

012341/12/13/34/45/3

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

012341/12/13/34/45/3

dusuk[4] = 3 ≠ indeks[4] = 5 → 4 kök değil, yığında kalır.

012341/12/13/34/35/3

scc(4) döndü: dusuk[3] = min(4, dusuk[4] = 3) = 3. dusuk[3] = 3 ≠ indeks[3] = 4 → 3 kök değil, yığında kalır.

012341/12/13/34/35/3

scc(3) döndü: dusuk[2] = min(3, dusuk[3] = 3) = 3. dusuk[2] = indeks[2] = 3 → 2 köktür; 4, 3, 2 çekilip yazdırılır: SCC {2, 3, 4}.

012341/12/13/34/35/3

scc(2) döndü: dusuk[1] = min(1, dusuk[2] = 3) = 1. dusuk[1] = 1 ≠ indeks[1] = 2 → 1 kök değil, yığında kalır.

012341/12/13/34/35/3

scc(1) döndü: dusuk[0] = min(1, dusuk[1] = 1) = 1. dusuk[0] = indeks[0] = 1 → 0 köktür; 1, 0 çekilip yazdırılır: SCC {0, 1}.

012341/12/13/34/35/3

Bitti: önce {2, 3, 4}, sonra {0, 1} bulundu. SCC'ler ters topolojik sırada çıkar: {0, 1} → {2, 3, 4} kenarı vardır.

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();
  }
}

Çıktı Sorusu · Tarjan SCC

Soru 22: Yığında mı Denetimi

Tarjan kodunda else if (yiginda[w]) satırı yalnızca else yapılırsa (ziyaret edilmiş her w için dusuk[v] = min(dusuk[v], indeks[w])), ziyaret edilmemiş her düğümden 0, 1, 2, 3 sırasıyla scc çağıran program ne yazdırır? Doğru kod ne yazdırırdı?

0132
Cevabı göster

Doğru kod: 1 0 ve 3 2 (iki satır).

Hatalı kod: yalnızca 1 0. scc(2)'de indeks[2] = 3, scc(3)'te indeks[3] = 4; 3 → 2 ile dusuk[3] = 3. Sonra 3 → 0 kenarı: 0 bitmiş bir SCC'dedir ama denetim kalktığı için dusuk[3] = min(3, indeks[0] = 1) = 1 olur. Dönüşte dusuk[2] = 1 ≠ 3 → 2 kök sayılmaz; {2, 3} hiç yazdırılmaz, yığında kalır.

Bitmiş SCC'lere giden kenarlar yok sayılmalıdır; aksi hâlde kökler kaybolur.

Çıktı Sorusu · Tarjan SCC

Soru 23: Tarjan Çıktısı

Komşu listeleri artan sıradadır. Tarjan izleme sorusundaki scc metodu scc(0) ile çağrılıyor. Hangi satırlar hangi sırayla yazdırılır?

0162345
Cevabı göster

Çıktı (satır satır):

5 4
3 2 1
6
0

DFS 0 → 1 → 2 → 3 iner; 3 → 1 geri kenarı dusuk[3] = 2 yapar. 2 → 4 → 5 → 4: {4, 5} kökü 4 (indeks 5) olduğundan ilk bu bileşen çıkar. Sonra {1, 2, 3} (kök 1), 0'a dönülünce 0 → 6 ile {6}, en son {0} çıkar.

Her SCC, kökü bittiği anda yazdırılır; sıra ters topolojik sıradır.

Çoktan Seçmeli · Tarjan SCC

Soru 24: Tarjan ve Kosaraju

Tarjan ve Kosaraju algoritmaları için aşağıdakilerden hangisi yanlıştır?

C yanlıştır: enDüşükBağ başta indekse eşittir ve yalnızca min ile güncellenir; hiçbir zaman indeksin üstüne çıkamaz. enDüşükBağ = indeks kök demektir. A, B ve D doğrudur; Kosaraju ters çizge için ek O(V + E) bellek kullanır.

Çıktı Sorusu · Uygulamalar

Soru 25: Ters Bitiş Sırası

Döngüsüz yönlü çizgede (DAG) komşu listeleri artan sıradadır. Program ne yazdırır?

051234
void dfsBitis(int v) {
  ziyaret[v] = true;
  for (int w : komsu[v])
    if (!ziyaret[w]) dfsBitis(w);
  yigin.push(v);           // bitince it
}
// main: ziyaret edilmemiş her v için
for (int v = 0; v < n; v++)
  if (!ziyaret[v]) dfsBitis(v);
while (!yigin.isEmpty())
  System.out.print(yigin.pop() + " ");
Cevabı göster

Bitiş sırası: 4, 3, 1, 2, 0, 5 (dfsBitis(0): 0 → 1 → 3 → 4; 4, 3, 1 biter; 2 biter, 0 biter; sonra dfsBitis(5): 5 biter).

Yığından çekilen sıra (ters bitiş): 5 0 2 1 3 4

Her u → v kenarında v, u'dan önce biter; bu yüzden ters bitiş sırasında u önce gelir. Kahn bu çizgede 0 5 1 2 3 4 verir; ikisi de geçerlidir. Zaman O(V + E).

Adım Adım Çalıştırma · Uygulamalar

Soru 26: Kahn Algoritması İzleme

kahn() hangi topolojik sırayı yazdırır? Giriş derecelerini ve kuyruğu izleyin.

013245gd=0gd=0gd=2gd=2gd=1gd=2kuyrukboş

DAG: kenarlar 0→2, 0→3, 1→3, 1→4, 3→2, 2→5, 4→5. Giriş dereceleri sayıldı (etiketler).

013245gd=0gd=0gd=2gd=2gd=1gd=2kuyruk01

Giriş derecesi 0 olanlar (0, 1) kuyruğa kondu: önlerinde bekleyen iş yok.

013245gd=0gd=0gd=1gd=1gd=1gd=2kuyruk1

0 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 2 (1), 3 (1). Kuyruğa ekleme yok.

013245gd=0gd=0gd=1gd=0gd=0gd=2kuyruk34

1 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 3 (0), 4 (0). 3, 4 kuyruğa eklendi.

013245gd=0gd=0gd=0gd=0gd=0gd=2kuyruk42

3 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 2 (0). 2 kuyruğa eklendi.

013245gd=0gd=0gd=0gd=0gd=0gd=1kuyruk2

4 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 5 (1). Kuyruğa ekleme yok.

013245gd=0gd=0gd=0gd=0gd=0gd=0kuyruk5

2 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 5 (0). 5 kuyruğa eklendi.

013245gd=0gd=0gd=0gd=0gd=0gd=0kuyrukboş

5 çıkarıldı, yazdırıldı. Çıkan kenarı yok.

013245gd=0gd=0gd=0gd=0gd=0gd=0kuyrukboş

Kuyruk boş; 6 düğümün hepsi çıktı → çizge döngüsüz. Topolojik sıra: 0 1 3 4 2 5.

void kahn() {
  int[] gd = new int[n];    // giriş dereceleri
  for (int v = 0; v < n; v++)
    for (int w : komsu[v]) gd[w]++;
  Queue<Integer> kuyruk = new LinkedList<>();
  for (int v = 0; v < n; v++)
    if (gd[v] == 0) kuyruk.add(v);
  while (!kuyruk.isEmpty()) {
    int v = kuyruk.poll();
    System.out.print(v + " ");
    for (int w : komsu[v])
      if (--gd[w] == 0) kuyruk.add(w);
  }
}

Çoktan Seçmeli · Uygulamalar

Soru 27: Geçersiz Topolojik Sıra

Kahn sorusundaki DAG için aşağıdaki sıralardan hangisi topolojik sıra değildir?

013245

A: 3 → 2 kenarı vardır; topolojik sırada 3, 2'den önce gelmelidir. A'da 2, 3'ten önce yazılmış. Diğer üçü her u → v kenarında u'yu önce yazar; topolojik sıra tek değildir (Kahn kuyruk sırasına göre bunlardan birini, 0 1 3 4 2 5'i verir).

Çıktı Sorusu · Uygulamalar

Soru 28: Döngülü Çizgede Kahn

Kahn izleme sorusundaki kahn() metodu bu yönlü çizgede çalıştırılıyor. Ne yazdırır? Sonuçtan ne anlaşılır?

012345
Cevabı göster

Çıktı: 0 4 5

Giriş dereceleri: 1 → 2 (0'dan ve 3'ten), 2, 3, 4, 5 → 1. Başta yalnızca 0 kuyrukta. 0 çıkınca gd[1] = 1, gd[4] = 0; 4 çıkınca 5 eklenir. 1, 2, 3'ün dereceleri hiç 0'a inmez: birbirlerini beklerler.

Yazdırılan düğüm sayısı 3 < V = 6 → çizgede döngü vardır (1 → 2 → 3 → 1); topolojik sıra yoktur. Kahn bu yüzden döngü testi olarak da kullanılır.

Çoktan Seçmeli · Uygulamalar

Soru 29: Köprü Koşulu

Yönsüz bir çizgede DFS yapılıyor; keşif(v) keşif sırası, enDüşükBağ(w) ise w'nin alt ağacından tek bir geri kenarla ulaşılabilen en küçük keşif değeridir. DFS ağacındaki v–w kenarı (w çocuk) ne zaman köprüdür?

B: w'nin alt ağacından v'ye ya da v'nin atalarına geri kenar yoksa, v–w silinince alt ağaç kopar. A (≥) eklem noktası koşuludur: alt ağaç v'ye dönebiliyorsa v–w köprü değildir ama v yine de eklem noktası olabilir. D yalnızca w'nin v'den hemen sonra keşfedildiğini söyler.

Klasik Soru · Uygulamalar

Soru 30: Bağlı Bileşen Sayısı

Yönsüz bir çizgenin bağlı bileşen sayısını bulan bir algoritma tarif edin ve karmaşıklığını verin. Yandaki çizgede kaç bileşen vardır ve DFS hangi düğümlerden başlatılır?

012345678
Cevabı göster
sayac = 0
her v = 0..n−1 için:
  eğer ziyaret[v] değilse:
    sayac++
    DFS(v)   // ya da BFS(v)

Her DFS, başladığı düğümün bileşeninin tamamını işaretler; yeni bir başlatma yeni bir bileşen demektir.

Bu çizgede 3 bileşen: {0, 1, 2}, {3, 4}, {5, 6, 7, 8}. DFS 0, 3 ve 5'ten başlatılır.

Her düğüm bir kez işaretlenir, her liste bir kez taranır: O(V + E) (matrisle O(V²)). Yönlü çizgede bu sayım bileşen sayısını vermez (Kaç Kez Başlatılır? sorusu).

Son

Bölüm 4.1: Çizge Gezinme Algoritmaları: Çalışma Soruları
Konu anlatımı: Çizge gezinme sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.