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