Menu
Coddy logo textTech

Derinlik Öncelikli Arama (DFS)

Son güncelleme

Derinlik öncelikli arama, bir grafı geri dönmeden önce her dal boyunca mümkün olduğunca derine giderek keşfeder. Bir kaynak düğümden başlayarak bir komşuyu, ardından o komşunun komşusunu ve bir çıkmaza (ziyaret edilmemiş komşusu olmayan bir düğüm) ulaşana kadar bu şekilde devam eder; o noktada geri döner ve bir sonraki dalı dener. Yukarıda oynata basarak bir yol boyunca aşağı inmesini, dibe ulaşmasını ve geri çıkmasını izleyin.

DFS doğal olarak bir yığınla ifade edilir: ya açık bir yığın (burada canlandırıldığı gibi) ya da özyineleme yoluyla çağrı yığını. Her düğüm ve kenarı bir kez ziyaret eder, bu nedenle V köşe ve E kenar içeren bir graf için O(V + E) zamanda ç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)Yığın + ziyaret edilenler kümesi, en kötü durumda tüm düğümler
GezinmeÖnce en derinDiğerlerinden önce bir dalı sonuna kadar izler
Veri yapısıYığın (veya özyineleme)LIFO sırası derinlik öncelikli davranışı yönlendirir

Adım adım

AdımNe olur
1Kaynak düğümü yığına ekle.
2Bir düğüm çıkar; zaten ziyaret edildiyse atla.
3Onu ziyaret edildi olarak işaretle ve ona ulaşan kenarı kaydet.
4Ziyaret edilmemiş tüm komşularını yığına ekle.
5Yığın boşalana kadar tekrarla.

Çözümlü örnek

A → [B, C], B → [D], C → [E] grafında A'dan başlayan yinelemeli DFS; komşular listelenen sırada yığına eklenir (LIFO yığını en son ekleneni önce çıkarır):

AdımYığın (üst sağda)Ziyaret edilenlerİşlem
1[A]{}Kaynak A'yı ekle.
2[B, C]{A}A'yı çıkar, ziyaret edildi işaretle, komşuları B sonra C'yi ekle.
3[B, E]{A, C}C'yi çıkar, ziyaret edildi işaretle, komşu E'yi ekle.
4[B]{A, C, E}E'yi çıkar, ziyaret edildi işaretle, komşu yok.
5[D]{A, C, E, B}B'yi çıkar, ziyaret edildi işaretle, komşu D'yi ekle.
6[]{A, C, E, B, D}D'yi çıkar, ziyaret edildi işaretle, yığın boş: tamamlandı.

DFS ne zaman kullanılır

Şu durumda kullanınŞu durumda kaçının
Döngü tespiti, topolojik sıralama veya bağlı bileşenleri bulmaya ihtiyacınız var.Ağırlıksız bir grafta en kısa yola ihtiyacınız var: bunu DFS değil BFS yapar.
Graf geniş ve sığdır, bu yüzden yığın çok sayıda sınır düğümü içeren bir kuyruktan çok daha az bellek kullanır.Graf çok derindir ve özyineleme kullanıyorsunuz: çağrı yığını taşabilir.
Labirent çözme veya geri izlemeli aramada olduğu gibi yolları kapsamlı şekilde keşfetmek istiyorsunuz.Düğümleri kaynaktan uzaklık sırasına göre keşfetmeniz gerekiyor.
Erişilebilirliği veya iki düğüm arasında bir yol olup olmadığını kontrol ediyorsunuz.Bulunan yolda en az sayıda kenarı garanti etmeniz gerekiyor.

Depth-First Search kodu

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

Python ile Depth-First Search kodu

Python
1def dfs(graph, node, visited):2    visited.add(node)3    order = [node]4    for neighbor in graph[node]:5        if neighbor not in visited:6            order.extend(dfs(graph, neighbor, visited))7    return order8
9
10graph = {11    "A": ["B", "C"],12    "B": ["D", "E"],13    "C": ["F"],14    "D": [],15    "E": ["F"],16    "F": [],17}18
19order = dfs(graph, "A", set())20print("DFS order:", " -> ".join(order))
Bu kodu Python Playground'da çalıştır

Derinlik Öncelikli Arama SSS

DFS'nin zaman karmaşıklığı nedir?
DFS, V köşe sayısı ve E kenar sayısı olmak üzere O(V + E) zamanda çalışır; çünkü her köşeyi bir kez ziyaret eder ve her kenara bir kez bakar. Yığın ve ziyaret edilenler kümesi için O(V) alan kullanır.
DFS ile BFS arasındaki fark nedir?
DFS bir yığın kullanır ve geri dönmeden önce bir dal boyunca derine dalar; BFS ise bir kuyruk kullanır ve seviye seviye, önce en yakın düğümleri keşfeder. BFS ağırlıksız bir grafta en kısa yolu bulur; DFS bulamaz ama geniş graflarda daha az bellek kullanır ve döngü tespiti ile topolojik sıralama gibi görevler için doğaldır.
DFS özyinelemeli mi yoksa yinelemeli mi?
İkisi de işe yarar. Özyinelemeli sürüm programın çağrı yığınını örtük olarak kullanır ve çok özdür; yinelemeli sürüm açık bir yığın kullanır (buradaki animasyon gibi) ve büyük graflarda derin özyineleme kaynaklı yığın taşmalarını önler.
BFS yerine DFS'yi ne zaman kullanmalıyım?
Tüm yolları keşfetmeniz gerektiğinde DFS kullanın: döngü tespiti, topolojik sıralama, bağlı bileşenler veya labirent çözme gibi geri izlemeli arama. Ayrıca geniş graflarda daha az bellek kullanır, çünkü yığın aynı anda yalnızca bir dalın sınırını tutar. Ağırlıksız bir grafta en kısa yola veya düğümlere kaynaktan uzaklık sırasına göre ihtiyacınız olduğunda BFS'ye başvurun.
DFS en kısa yolu bulabilir mi?
Güvenilir biçimde bulamaz. DFS bulduğu ilk yolu döndürür ki bu genellikle en az kenarlı yol değildir, çünkü eşit biçimde yayılmak yerine derine dalmaya odaklanır. Ağırlıksız bir grafta en kısa yollar için BFS, ağırlıklı graflar için Dijkstra algoritmasını kullanın.
DFS neden bir ziyaret edilenler kümesine ihtiyaç duyar?
Ziyaret edilenler kümesi olmadan DFS, birden fazla yolla ulaşılabilen düğümleri yeniden ziyaret eder ve döngülü bir grafta sonsuza dek döner. Bir düğümü çıkarırken ziyaret edildi olarak işaretlemek (ve zaten ziyaret edilmiş çıkarmaları atlamak) her düğümün bir kez işlenmesini garanti eder ve çalışma süresini O(V + E) seviyesinde tutar. Yaygın bir hata, çıkarırken düğümleri ziyaret edildi işaretleyip yine de yinelenenleri eklemektir; bu doğrudur ama yığında atlanması gereken eski girişler bırakabilir.
Coddy programming languages illustration

Coddy ile algoritmalarda ustalaş

BAŞLA