Önce Genişlik Önce Derinlik


172

Bir Ağacı / Grafiği Gezerken Önce Önce Genişlik ve Derinlik arasındaki fark nedir? Herhangi bir kodlama veya sözde kod örneği harika olurdu.


6
Eğer (wikipedia kontrol ettin ilk derinliği , ilk genişliğini )? Bu sayfalarda çok güzel resimlerle birlikte kod örnekleri var.
rmeador

Ben de düşündüm, ama sonra verilen örnekler wikipedia'da bulunanlardan biraz daha güzel ....
jonnybazookatone

Yanıtlar:


292

Bu iki terim, ağaçta yürümek için iki farklı yol arasında ayrım yapar.

Farkı göstermek muhtemelen en kolay yoldur. Ağacı düşünün:

    A
   / \
  B   C
 /   / \
D   E   F

Bir derinlik ilk geçişi bu sırada düğümleri ziyaret edeceğini

A, B, D, C, E, F

Eğer tüm yol gitmek Bildirimi aşağı geçmeden önce tek bacak.

Bu ilk sırada bir genişlik ilk geçişi düğümü ziyaret edecekti

A, B, C, D, E, F

Burada tüm yol boyunca çalışıyoruz aşağı inmeden önce her seviyede .

(Geçiş emirlerinde bir miktar belirsizlik olduğunu ve ağacın her seviyesinde "okuma" sırasını korumak için hile yaptığımı unutmayın. Her iki durumda da C'den önce veya sonra B'ye ulaşabilirim ve benzer şekilde E, F'den önce veya sonra. Bu önemli olabilir veya olmayabilir, uygulamanıza bağlıdır ...)


Her iki geçiş türü sözde kodla elde edilebilir:

Store the root node in Container
While (there are nodes in Container)
   N = Get the "next" node from Container
   Store all the children of N in Container
   Do some work on N

İki çapraz emir arasındaki fark, seçiminde yatmaktadır Container.

  • İçin derinlik ilk yığın kullanır. (Özyinelemeli uygulama çağrı yığını kullanır ...)
  • For genişliğine ilk bir kuyruk kullanabilir.

Özyinelemeli uygulama,

ProcessNode(Node)
   Work on the payload Node
   Foreach child of Node
      ProcessNode(child)
   /* Alternate time to work on the payload Node (see below) */

Özyineleme, çocuğu olmayan bir düğüme ulaştığınızda sona erer, bu nedenle sonlu, asiklik grafikler için sonlanması garanti edilir.


Bu noktada hâlâ biraz kandırdım. Küçük bir zekayla , düğümleri bu sırayla da çalışabilirsiniz :

D, B, E, F, C, A

Bu, önce derinliğin bir varyasyonu, ağaçta yürüene kadar her düğümde çalışmam. Bununla birlikte , çocuklarını bulmak için yolda daha yüksek düğümleri ziyaret ettim .

Bu geçiş, özyinelemeli uygulamada oldukça doğaldır (ilk "İş" satırı yerine yukarıdaki "Alternatif zaman" satırını kullanın) ve açık bir yığın kullanırsanız çok zor değil , ancak bir egzersiz olarak bırakacağım.


@dmckee Teşekkürler! "Düğümde yük üzerinde çalışmak" demek istediğine inanıyorum, değil mi?
batbrat

4
Önek ( A, B, D, C, E, F- sunulan ilk), infix ( D, B, A, E, C, F- sıralama için kullanılır: AVL ağacı olarak ekleyin ve ardından infix okuyun) veya postfix ( D, B, E, F, C, Asunulan alternatif) geçişi almak için derinlik ilk sürümünü değiştirebileceğinizi belirtmek gerekir . İsimler kökü işlediğiniz konuma göre verilir. Ekin sadece ikili ağaçlar için gerçekten mantıklı olduğuna dikkat edilmelidir. @batbrat bu isimler ... Sorduğunuz zamandan beri, muhtemelen zaten biliyorsunuz.
Theraot

@Theraot bunu eklediğiniz için teşekkürler! Evet, bu tür çapraz geçişleri ve Infix'in neden sadece ikili ağaçlar için anlamlı olduğunu biliyorum.
batbrat

Hangi çözümün daha iyi bir alana veya zaman karmaşıklığına sahip olduğuna nasıl karar verilir?
IgorGanapolsky

1
@IgorGanapolsky Prensipte her ikisi için de aynı olmalıdır (sonuçta, aslında aynı kodu kullanırlar). Daha ilginç bir soru, önbelleği ve çalışma setini nasıl etkilediği olacaktır, ancak bence bu, ağacın morfolojisine bağlı olacaktır.
dmckee --- eski moderatör kedi yavrusu

95

Şartları anlama:

Bu resim size genişlik ve derinlik kelimelerinin kullanıldığı bağlam hakkında fikir vermelidir .

Genişlik ve Derinliği Anlamak


Derinlik öncelikli arama:

Derinlik öncelikli arama

  • Derinlik-birinci arama algoritması, başlangıç ​​noktasından mümkün olduğunca çabuk uzaklaşmak istiyormuş gibi davranır.

  • Genellikle Stackbir çıkmaz noktaya ulaştığında nereye gitmesi gerektiğini hatırlamak için a kullanır .

  • Uyulması gereken kurallar: İlk köşe A'yı Stack

    1. Mümkünse bitişik olmayan bir tepe noktasını ziyaret edin, ziyaret edilmiş olarak işaretleyin ve yığının üzerine itin.
    2. Kural 1'i uygulayamıyorsanız, mümkünse yığından bir tepe noktası açın.
    3. Kural 1 veya Kural 2'yi izleyemiyorsanız, işleminiz tamamlanmıştır.
  • Java kodu:

    public void searchDepthFirst() {
        // Begin at vertex 0 (A)
        vertexList[0].wasVisited = true;
        displayVertex(0);
        stack.push(0);
        while (!stack.isEmpty()) {
            int adjacentVertex = getAdjacentUnvisitedVertex(stack.peek());
            // If no such vertex
            if (adjacentVertex == -1) {
                stack.pop();
            } else {
                vertexList[adjacentVertex].wasVisited = true;
                // Do something
                stack.push(adjacentVertex);
            }
        }
        // Stack is empty, so we're done, reset flags
        for (int j = 0; j < nVerts; j++)
            vertexList[j].wasVisited = false;
    }
    
  • Uygulamalar : Derinlik-ilk aramalar genellikle oyunların simülasyonlarında (ve gerçek dünyadaki oyun benzeri durumlar) kullanılır. Tipik bir oyunda birkaç olası eylemden birini seçebilirsiniz. Her seçim, her biri daha fazla seçeneğe yol açan daha fazla seçeneğe yol açar ve böylece sürekli genişleyen ağaç şeklindeki bir olasılık grafiğine dönüşür.


Genişlik İlk Arama:

Genişlik İlk Arama

  • Genişlik ilk arama algoritması, başlangıç ​​noktasına mümkün olduğunca yakın kalmayı sever.
  • Bu tür bir arama genellikle a Queue.
  • İzlenecek kurallar: Tepe A'yı geçerli köşe noktası yap
    1. Geçerli tepe noktasına bitişik olan bir sonraki ziyaret edilmemiş tepe noktasını (varsa) ziyaret edin, işaretleyin ve kuyruğa ekleyin.
    2. Kural 1'i gerçekleştiremiyorsanız, çünkü daha fazla köşe noktası yok, bir tepe noktasını kuyruktan kaldırın (mümkünse) ve geçerli köşe noktası yapın.
    3. Kural 2, kuyruk boş olduğu için gerçekleştiremiyorsanız, işleminiz tamamlanmıştır.
  • Java kodu:

    public void searchBreadthFirst() {
        vertexList[0].wasVisited = true;
        displayVertex(0);
        queue.insert(0);
        int v2;
        while (!queue.isEmpty()) {
            int v1 = queue.remove();
            // Until it has no unvisited neighbors, get one
            while ((v2 = getAdjUnvisitedVertex(v1)) != -1) {
                vertexList[v2].wasVisited = true;
                // Do something
                queue.insert(v2);
            }
        }
        // Queue is empty, so we're done, reset flags
        for (int j = 0; j < nVerts; j++) 
            vertexList[j].wasVisited = false;
    }
    
  • Uygulamalar : Önce genişlik araması ilk olarak başlangıç ​​noktasından bir kenar uzaktaki tüm köşeleri, sonra iki kenar uzaktaki tüm köşeleri vb. Bulur. Başlangıç ​​tepe noktasından belirli bir tepe noktasına en kısa yolu bulmaya çalışıyorsanız bu yararlıdır.

Umarım bu, Önce Genişlik İlk ve Derinlik İlk aramalarını anlamak için yeterli olmalıdır. Daha fazla okumak için Robert Lafore'nin mükemmel bir veri yapıları kitabından Grafikler bölümünü öneriyorum.


6
On oy daha toplasaydım, yapardım.
snr

@snr bir ödül verebilirsiniz;)
Kar

@ Direktiflerini söylersen söyleyebilirim. Nasıl yapacağımı bilmiyorum.
Snr

Teşekkürler @snr, ilk ödülümü almaktan çok memnunum. Çok minnettarım.
Yogesh Umesh Vaity

1
@ Teşekkürler, cevabımı yararlı bulduğunuz için memnunum.
Yogesh Umesh Vaity

4

Bu ikili ağaç göz önüne alındığında:

resim açıklamasını buraya girin

İlk Genişlik:
Her seviye boyunca soldan sağa doğru ilerleyin.

"Ben G, çocuklarım D ve ben, torunlarım B, E, H ve K, torunları A, C, F"

- Level 1: G 
- Level 2: D, I 
- Level 3: B, E, H, K 
- Level 4: A, C, F

Order Searched: G, D, I, B, E, H, K, A, C, F

Derinlik İlk Geçişi:
Geçiş, bir seferde tüm seviyeler boyunca yapılmaz. Bunun yerine, çapraz geçiş önce ağacın DERİNLİĞİNE (kökten yaprağa) dalar. Ancak, yukarı ve aşağıdan biraz daha karmaşıktır.

Üç yöntem vardır:

1) PREORDER: ROOT, LEFT, RIGHT.
You need to think of this as a recursive process:  
Grab the Root. (G)  
Then Check the Left. (It's a tree)  
Grab the Root of the Left. (D)  
Then Check the Left of D. (It's a tree)  
Grab the Root of the Left (B)  
Then Check the Left of B. (A)  
Check the Right of B. (C, and it's a leaf node. Finish B tree. Continue D tree)  
Check the Right of D. (It's a tree)  
Grab the Root. (E)  
Check the Left of E. (Nothing)  
Check the Right of E. (F, Finish D Tree. Move back to G Tree)  
Check the Right of G. (It's a tree)  
Grab the Root of I Tree. (I)  
Check the Left. (H, it's a leaf.)  
Check the Right. (K, it's a leaf. Finish G tree)  
DONE: G, D, B, A, C, E, F, I, H, K  

2) INORDER: LEFT, ROOT, RIGHT
Where the root is "in" or between the left and right child node.  
Check the Left of the G Tree. (It's a D Tree)  
Check the Left of the D Tree. (It's a B Tree)  
Check the Left of the B Tree. (A)  
Check the Root of the B Tree (B)  
Check the Right of the B Tree (C, finished B Tree!)  
Check the Right of the D Tree (It's a E Tree)  
Check the Left of the E Tree. (Nothing)  
Check the Right of the E Tree. (F, it's a leaf. Finish E Tree. Finish D Tree)...  
Onwards until...   
DONE: A, B, C, D, E, F, G, H, I, K  

3) POSTORDER: 
LEFT, RIGHT, ROOT  
DONE: A, C, B, F, E, D, H, K, I, G

Kullanımı (aka, neden umursuyoruz):
Derinlik İlk Geçiş yöntemlerinin bu basit Quora açıklamasından ve bunların yaygın olarak nasıl kullanıldığından gerçekten keyif aldım:
"Sıralı Geçiş değerleri [BST (ikili arama ağacı) için) basacaktır "
" Ön sipariş geçişi [ikili arama ağacının] bir kopyasını oluşturmak için kullanılır. "
"Postorder geçişi [ikili arama ağacı] silmek için kullanılır."
https://www.quora.com/What-is-the-use-of-pre-order-and-post-order-traversal-of-binary-trees-in-computing


2

Her ikisini de yazmak için ilginç olacağını düşünüyorum, sadece bazı kod satırlarını değiştirerek size bir algoritma veya diğeri verecek, böylece dilleminizin ilk bakışta göründüğü kadar güçlü olmadığını göreceksiniz. .

Ben şahsen BFS'nin bir manzaraya taşkın olarak yorumlanmasını seviyorum: önce alçak irtifa alanları sular altında kalacak ve ancak o zaman yüksek irtifa alanları gelecektir. Coğrafya kitaplarında gördüğümüz gibi manzara yüksekliklerini izolinler olarak hayal ederseniz, BFS'nin tıpkı fizikte olduğu gibi aynı izolin altındaki tüm alanları aynı anda doldurduğunu görmek kolaydır. Böylece, yükseklikleri mesafe veya ölçeklendirilmiş maliyet olarak yorumlamak algoritma hakkında oldukça sezgisel bir fikir verir.

Bunu göz önünde bulundurarak, minimum genişleme ağacını kolayca, en kısa yolu ve diğer birçok minimizasyon algoritmasını bulmak için genişlik ilk aramanın arkasındaki fikri kolayca uyarlayabilirsiniz.

DFS'nin henüz sezgisel bir yorumunu görmedim (sadece labirentle ilgili standart olan, ancak BFS biri ve sel kadar güçlü değil), bu yüzden benim için BFS'nin yukarıda açıklandığı gibi fiziksel fenomenlerle daha iyi ilişkili olduğu görülüyor, DFS, rasyonel sistemlerde seçimler dillemiyle daha iyi ilişkilidir.

Bu yüzden benim için, doğal fenomenin gerçek hayatta yayılma modeline (enine) en iyi uyduğu yalanlar arasındaki fark.


1
Bunları benzer bir algoritma ile uygulayabilirsiniz, sadece DFS için yığın ve BFS için sıra kullanın. BFS ile ilgili sorun, şimdiye kadar görülen tüm düğümleri izlemeniz gerektiğidir. Fizikte DFS .. Alternatif evrenler hayal ediyorum ve yaşamla bir tane istiyorum, tüm kök çocukları, farklı büyük patlamalardır ve evrenin ölümüne kadar inersiniz, yaşam yok mu? Son çatallanmaya geri dönüp, hepsi tükenene kadar başka bir dönüş deneyin ve yeni evren için yeni fiziksel yasalar belirleyerek bir sonraki büyük patlamaya gidin. süper sezgisel. iyi bir sorun satranç tahtasında atı ile bir yol bulmaktır.
juanmf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.