Bölüm 4.1: Çizge Gezinme Algoritmaları
Ç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
ziyaretEdildiO(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
pollO(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?
| 0 | 1 | 2 | 3 | 4 | |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 0 | 0 |
| 2 | 0 | 1 | 0 | 1 | 0 |
| 3 | 0 | 1 | 0 | 0 | 0 |
| 4 | 0 | 0 | 0 | 1 | 0 |
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.
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.
dfs(0): 0 işaretlenir ve yazdırılır; çağrı yığınında tek çerçeve var.
0'ın komşusu 1 ziyaret edilmemiş → dfs(1): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.
1'in komşusu 2 ziyaret edilmemiş → dfs(2): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.
2 → 0 kenarı: 0 zaten ziyaretli (yığında (işi sürüyor)) → atlanır.
2 bitti, çağrı döner; kontrol 1'e geri gelir (geri dönüş).
1'in komşusu 4 ziyaret edilmemiş → dfs(4): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.
4 → 2 kenarı: 2 zaten ziyaretli (bitmiş) → atlanır.
4'ün komşusu 5 ziyaret edilmemiş → dfs(5): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.
5, 4, 1 bitti, çağrı döner; kontrol 0'a geri gelir (geri dönüş).
0'ın komşusu 3 ziyaret edilmemiş → dfs(3): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.
3 → 4 kenarı: 4 zaten ziyaretli (bitmiş) → atlanır.
3 bitti, çağrı döner; kontrol 0'a geri gelir (geri dönüş).
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.
Aynı çizge. Başlangıç düğümü 0 yığına itildi; henüz hiçbir düğüm işaretli değil.
0 çekildi: işaretlenir, yazdırılır; komşuları 1, 3 sırayla itilir → en son itilen 3 en üstte.
3 çekildi: işaretlenir, yazdırılır; komşusu 4 itilir.
4 çekildi: işaretlenir, yazdırılır; komşuları 2, 5 sırayla itilir → en son itilen 5 en üstte.
5 çekildi: işaretlenir, yazdırılır; komşusu yok.
2 çekildi: işaretlenir, yazdırılır; komşusu 0 itilir.
0 çekildi ama zaten ziyaretli → atlanır. Bir düğüm yığına birden çok kez girebilir.
1 çekildi: işaretlenir, yazdırılır; komşuları 2, 4 sırayla itilir → en son itilen 4 en üstte.
4 çekildi ama zaten ziyaretli → atlanır. Bir düğüm yığına birden çok kez girebilir.
2 çekildi ama zaten ziyaretli → atlanır. Bir düğüm yığına birden çok kez girebilir.
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?
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?
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?
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ı?
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.
Yönsüz çizge, komşu listeleri artan sırada. 0 işaretlendi ve kuyruğa kondu (katman 0).
0 çıkarıldı ve yazdırıldı. Yeni komşular 3, 5 işaretlenip kuyruğun sonuna eklendi (uzaklık 1).
3 çıkarıldı ve yazdırıldı. Yeni komşular 1, 6 işaretlenip kuyruğun sonuna eklendi (uzaklık 2).
5 çıkarıldı ve yazdırıldı. Yeni komşular 2 işaretlenip kuyruğun sonuna eklendi (uzaklık 2).
1 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.
6 çıkarıldı ve yazdırıldı. Yeni komşular 4 işaretlenip kuyruğun sonuna eklendi (uzaklık 3).
2 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.
4 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.
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?
Cevabı göster
Sıra: A B D C E G F H
| düğüm | A | B | C | D | E | F | G | H |
|---|---|---|---|---|---|---|---|---|
| uzaklık | 0 | 1 | 2 | 1 | 2 | 3 | 2 | 3 |
| ebeveyn | — | A | B | A | B | C | D | G |
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?
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?
Cevabı göster
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?
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.
Çizge: 0 ⇄ 1, 1 → 2, 2 → 3 → 4 → 2. indeks[w] == 0 ziyaret edilmedi demektir; düğüm yanındaki etiket indeks/dusuk.
scc(0): indeks = dusuk = 1; 0 yığına itilir.
0 → 1: 1 ziyaret edilmemiş → scc(1): indeks = dusuk = 2; yığına itilir.
1 → 0: 0 yığında → dusuk[1] = min(2, indeks[0] = 1) = 1.
1 → 2: 2 ziyaret edilmemiş → scc(2): indeks = dusuk = 3; yığına itilir.
2 → 3: 3 ziyaret edilmemiş → scc(3): indeks = dusuk = 4; yığına itilir.
3 → 4: 4 ziyaret edilmemiş → scc(4): indeks = dusuk = 5; yığına itilir.
4 → 2: 2 yığında → dusuk[4] = min(5, indeks[2] = 3) = 3.
dusuk[4] = 3 ≠ indeks[4] = 5 → 4 kök değil, yığında kalır.
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.
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}.
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.
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}.
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ı?
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?
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?
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.
DAG: kenarlar 0→2, 0→3, 1→3, 1→4, 3→2, 2→5, 4→5. Giriş dereceleri sayıldı (etiketler).
Giriş derecesi 0 olanlar (0, 1) kuyruğa kondu: önlerinde bekleyen iş yok.
0 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 2 (1), 3 (1). Kuyruğa ekleme yok.
1 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 3 (0), 4 (0). 3, 4 kuyruğa eklendi.
3 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 2 (0). 2 kuyruğa eklendi.
4 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 5 (1). Kuyruğa ekleme yok.
2 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 5 (0). 5 kuyruğa eklendi.
5 çıkarıldı, yazdırıldı. Çıkan kenarı yok.
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?
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?
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?
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).