İkili Arama ağacında Sil?

oy
0

Kitabın kullanılan düğüm algoritmasını silmek ikili ağacın içinden okuyorum Veri Yapıları ve Algoritmalar: Örnekler ile Açıklamalı Referans

sayfa 34, vaka 4 (sağ ve sol alt ağaçlar hem sahiptir düğümü Sil) kitabında çalışmıyor görünüyor açıklanan aşağıdaki algoritma üzerinde, muhtemelen birisi bana eksik ben bana yardımcı olabilir yanlış olabilir.

//Case 4
get largestValue from nodeToRemove.Left
FindParent(largestValue).Right <- 0
nodeToRemove.Value<-largestValue.Value

Aşağıdaki satır alt ağacından en büyük değeri siler yok nasıl FindParent(largestValue).Right <- 0

Oluştur 29/06/2010 saat 21:09
kaynak kullanıcı
Diğer dillerde...                            


5 cevaplar

oy
1

Fikir basit sol taraftaki büyük düğümden değerini alıp siliniyor düğüme taşıyın yani hiç düğümü silmeyin, bu içeriği sadece değiştirmektir. O zaman "silinmiş" düğüm taşındı değerle düğümünü erik. Bu daha geniş hepsi hepsi doğru çocuklar var daha çocukları ve küçük kalan daha her düğümün değeri ile ağaç sipariş tutar.

Cevap 29/06/2010 saat 21:16
kaynak kullanıcı

oy
1

Ben sözde kodu anlamak, bu genel durumda çalışır, ancak durum "sol alt ağaç bir düğüm" başarısız olur. Güzel yakalayış.

sol alt ağaç (aynı zamanda eski largest_value düğümü NULL'ları) bulunuyor dan etkin bir şekilde largest_value ile node_to_remove değiştirir.

Bir BST içinde, node_to_remove sol alt ağaç her node_to_remove daha küçük olacağını unutmayın. node_to_remove sağ alt ağaç her node_to_remove daha büyük olacaktır. Eğer sol alt ağacındaki büyük düğüm alırsak Yani, değişmeyen koruyacaktır.

bu bir "alt ağaç durumda bir düğüm" ise, bunun yerine doğru alt ağacı tahrip edeceğiz. Lame :(

Vivin işaret ettiği gibi, aynı zamanda largestNode sol çocukları tekrar eklemeniz başarısız olur.

Cevap 29/06/2010 saat 21:16
kaynak kullanıcı

oy
6

iki çocuklu bir düğüm silerken, onun içinde sipariş halefi düğümü veya onun içinde sipariş selefi düğümü seçebilir ya. Bu durumda o düğümün içinde sipariş selefi düğümü bulma anlamına gelir (sol alt ağacın en sağdaki çocuk anlamına gelir) sol alt ağacın en büyük değeri, bulmaya çalışıyor.

Eğer yedek düğümü bulduktan sonra, aslında yok silmek Silinecek düğümü. Bunun yerine halefi düğümden değerini alıp silmek istediğiniz düğüm bu değeri depolar. Ardından, halefi düğümünü silin. Bunu yaparken size seçilen düğüm orijinal düğümün sol alt ağaçtaki tüm çocukların değerlerinden daha düşük bir değere sahip olacaktır emin olabilirsiniz çünkü ikili arama ağacı özelliğini korumak ve daha fazla olduğu değerlerden daha orijinal düğümün sağ alt ağaçtaki tüm çocukların.

DÜZENLE

Biraz daha sorunuzu okuduktan sonra ben sorunu bulduk düşünüyorum.

Genellikle ne ek olarak sahip deleteişlevin bir olduğu replace, söz konusu düğüm yerini işlevi. Sana bu kod satırını değiştirmeniz gerekir düşünüyorum:

FindParent(largestValue).Right <- 0

için:

FindParent(largestValue).Right <- largestValue.Left

Eğer largestValuedüğüm sol çocuğu yoktur, sadece almak nullya 0. Bir sol çocuk sahibi yoksa, o çocuk için bir yedek olur largestValuedüğüm. Yani haklısınız; Kod dikkate senaryoyu almaz largestValuedüğüm sol çocuk sahibi olabilir.

Başka DÜZENLEME

Yalnızca pasajı gönderdiniz beri, kod bağlam ne olduğundan emin değilim. Ama yayınlanmıştır olarak pasajı önerdiğiniz sorunu (yanlış düğüm değiştirme) var gibi görünüyor. Genellikle, orada üç olgu vardır, ama Snippet'inizdeki yorum diyor fark //Case 4(bu yüzden belki başka bağlam yoktur).

Daha önce, ben aslında ima deletegenellikle birlikte gelir replace. Eğer bulursanız largestValuedüğümü, iki basit durumlarda (hayır çocuklu düğüm ve bir çocuk düğüme) göre silin. İki çocuklu bir düğüm silmek için sözde koda bakarken, yani bu Yapacaklarından geçerli:

get largestValue from nodeToRemove.Left
nodeToRemove.Value <- largestValue.Value

//now replace largestValue with largestValue.Left    

if largestValue = largestValue.Parent.Left then   
   largestValue.Parent.Left <- largestValue.Left //is largestValue a left child?
else //largestValue must be a right child
   largestValue.Parent.Right <- largestValue.Left

if largestValue.Left is not null then
   largestValue.Left.Parent <- largestValue.Parent

Bir Veri Yapıları ve Algoritmalar kitap bu bölümünü terk edeceğini o kadar da yabancı, bu yüzden daha kolay hale getirmek için daha fazla kitap olduğunu düşünüyorum (üç standart durumlar vardır çünkü) birkaç olgu haline silme bölmek eğilimindeyim anlama.

Yukarıdaki kod çalıştığını kanıtlamak için aşağıdaki ağacını göz önünde bulundurun:

  8
 / \
7   9

Diyelim ki silmek istediğinizi varsayalım 8. Sen bulmaya largestValuegelen nodeToRemove.Left. Bu verir 7, sol alt ağaç sadece bir çocuğu vardır çünkü.

Sonra yapın:

nodeToRemove.Value <- largestValue.Value

Bu da demektir ki:

8.value <- 7.Value

veya

8.Value <- 7

Yani şimdi ağaç gibidir:

  7
 / \
7   9

Sen yedek düğüm kurtulmak gerekir ve böylece değiştirmek için gidiyoruz largestValueile largestValue.Left(ki null). Bunun için ilk önce çocuğun tür öğrenmek 7geçerli:

if largestValue = largestValue.Parent.Left then

Bu da demektir ki:

if 7 = 7.Parent.Left then

veya:

if 7 = 8.Left then

Yana 7is 8'nin sol çocuğa, değiştirmeniz gerekiyor 8.Leftile 7.Right( largestValue.Parent.Left <- largestValue.Left). Yana 7çocuk sahibi olmadığı, 7.Leftboş. Yani largestValue.Parent.Left(etkin bir şekilde sol çocuğu kaldırılır) null atanır. Yani bu şu ağacın ile bitirmek anlamına gelir:

  7
   \
    9
Cevap 29/06/2010 saat 21:17
kaynak kullanıcı

oy
0

Eğer baktığınızda Daha mantıklı olabilir Wikipedia'nın algoritmanın o kısmı üzerinde take:

Iki çocuklu bir düğüm silme : düğümü Çağrı "N" Silinecek. Bunun yerine N. silmeyin, onun içinde sipariş halefi düğümü veya onun içinde sipariş öncel düğümünü, "R" ya seçin. R değeri ile N değerini yerine, sonra R (Not: R, kendisi bir çocuk kadar sahip olur). Silme

verilen algoritma sipariş önceki düğümünü seçer unutmayın.

Düzenleme: R (Wikipedia'nın terminolojisini kullanmak için) ihtimalini eksik görünen bir çocuğu vardır. Bir özyinelemeli iyi çalışabilir silin.

Cevap 29/06/2010 saat 21:20
kaynak kullanıcı

oy
1

Sana çalışmıyor netleştirmek gerekebilir düşünüyorum.

Ben denemenin sorunun çözümüne yardımcı durumda bir ikili ağaçtaki silinmesi kavramını açıklayacağız.

Eğer silmek istediğiniz iki alt düğümlere ağacında bir düğüm olduğunu varsayalım Sağlar. Ağaçta Aşağıdaki düğüm b silmek istediğinizi Diyelim
           bir
         / \
       b c
     / \ / \
   d e f g

Biz bir düğüm sildiğinizde onun bağımlı düğümleri yeniden eklemeniz gerekir.

yani. Biz b sildiğinizde biz düğümleri d ve e tekrar eklemeniz gerekir.

Biz sol düğümleri değerindeki doğru düğümler daha az ve biliyoruz ebeveyn düğümleri sol ve sağ düğümün s değer arasında olduğunu. Bu durumda d <B ve b <e ise. Bu bir ikili ağacın tanımının bir parçasıdır.

Ne biraz daha az açıktır <a yani e. Yani bu e b yerini anlamına gelir. Şimdi biz d takın gerek e reattached var.

d <e önce de belirtildiği gibi bu yüzden e sol düğüm olarak e ekleyebilir.

silme artık tamamlanmıştır.

(Btw bu şekilde bağımlı düğümleri ağaca bir düğüm yukarı hareket ve yeniden düzenleyerek süreci bir düğüm teşvik olarak bilinir. Ayrıca diğer düğümleri silmeden bir düğümü tanıtabilirsiniz.)


           Bir
         / \
       D C
         \ / \
          e f g

Düğüm b deleteing başka mükemmel meşru bir sonuç olduğunu unutmayın. yerine düğüm e düğüm d teşvik seçtiyseniz ağaç şu şekilde görünecektir.


           Bir
         / \
       e c
     / / \
   D F g

Cevap 29/06/2010 saat 21:44
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more