Dengeli ikili arama ağaçları O (log n) aramalarını (veya benzer işlemleri) garanti etmek için gereklidir . Çok sayıda anahtarın rastgele yerleştirildiği ve / veya silindiği dinamik bir ortamda, ağaçlar aramalar için korkunç olan bağlantılı listelere dönüşebilir. Bu nedenle, bu etkiye karşı koyan çeşitli kendini dengeleyen ikili ağaçlar vardır ( AVL ağaçları veya yayvan ağaçları gibi ). Bu ağaçlar , ağacı yeniden dengeleyen farklı rotasyon türlerine dayanmaktadır .
rotasyonlar
Bu meydan okumada sadece tek sağ dönüşlere bakacağız, böyle bir dönüş (sol dönüş simetrik olacaktır) şöyle görünür:
5 3
/ \ / \
3 6 => 1 5
/ \ / \
1 4 4 6
Yaprakların Varsa 1
, 4
ya 6
bırakmıştı veya sağ alt ağaçlar bir rotasyon sadece onları orada tutmak olacaktır. Bu daha büyük bir ağacın alt ağacı ise, sadece düğümü 5
"keseriz" ve döndürülen ağacı (şimdi düğüm 3
) o düğüme "yeniden ekleriz" .
Meydan okuma
Bir ikili arama ağacı 1 ve bir anahtar verildiğinde, bu düğüm üzerindeki ağacı yukarıda açıklandığı gibi sağa döndürün. Yukarıdaki örnekte verilen anahtarı olacaktır 5
.
Kurallar ve G / Ç
- seçtiğiniz tuşlar ile test senaryolarının tuşları arasında bir bağlantı olduğu sürece tuşlar için herhangi bir tür kullanabilirsiniz.
[3,[]]
belirsizlik olmadığı sürece (örn. aksi belirtilmedikçe belirsiz) ve seçtiğiniz dil için doğal olan ikili ağaçlar için herhangi bir temsili seçebilirsiniz.- giriş her zaman ikili bir arama ağacı olacağından yinelenen anahtar yoktur
- anahtarın ağaçta olduğunu varsayabilirsiniz.
- anahtarı içeren düğümün sol çocuğu olduğunu varsayabilirsiniz.
- Eğer açabilir değil sağlanan anahtarının altında sağ alt ağacı varsayalım
- Eğer açabilir değil ağaç dönme önce dengesiz olduğunu varsayalım
- Eğer açabilir değil ağaç dönüşten sonra dengeli farz
- herhangi bir varsayılan G / Ç yöntemini kullanabilirsiniz
- gönderiminiz, ağacı döndüren veya çözümü yazdıran tam program olabilir bir işlev olabilir
Test senaryoları
Bu örnekler aşağıdaki gibi bir ağacı temsil eder
- eğer bir yapraksa:
[]
- eğer anahtarlı bir
x
ağaçsa ve her iki alt ağaç da yapraksa:[x]
- eğer anahtar
x
ve alt ağaçlara sahip bir ağaçsaleft
right
:[x,left,right]
İlk örnek Rotasyonlar bölümünde verilen örnektir . Herhangi bir nedenle bunların grafiksel bir temsiline ihtiyacınız varsa, işte 2 .
5 [5,[3,[1],[4]],[6]] -> [3,[1],[5,[4],[6]]]
5 [5,[3,[1],[4]],[]] -> [3,[1],[5,[4],[]]]
5 [5,[3,[],[4]],[6]] -> [3,[],[5,[4],[6]]]
5 [5,[3,[1],[]],[]] -> [3,[1],[5]]
4 [8,[4,[2,[1],[3]],[6,[5],[7]]],[12,[10,[9],[11]],[14,[13],[15]]]] -> [8,[2,[1],[4,[3],[6,[5],[7]]]],[12,[10,[9],[11]],[14,[13],[15]]]]
8 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]] -> [10,[6,[4,[2,[],[3]],[5]],[8,[7],[9]]],[11]]
10 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]] -> [8,[6,[4,[2,[],[3]],[5]],[7]],[10,[9],[11]]]
9 [6,[3,[2],[5]],[9,[8],[12,[11],[15,[14],[]]]]] -> [6,[3,[2],[5]],[8,[],[9,[],[12,[11],[15,[14],[]]]]]]
7 [7,[5,[3,[1],[4]],[6]],[8]] -> [5,[3,[1],[4]],[7,[6],[8]]]
15 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]] -> [17,[9,[5,[2,[0],[4]],[8]],[13,[11,[10],[12]],[15,[14],[16]]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]
21 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]] -> [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[19,[18],[21,[20],[24,[22],[25]]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]
1: yani herhangi bir düğüm için sol alt ağaçtaki tüm anahtarlar bu anahtardan daha küçük olacaktır ve sağ alt ağaçtaki tüm anahtarlar bundan daha büyük olacaktır
2: link-rot'ı önlemek için, onları yorum olarak yerleştirdim
data B=B[B]Int
daha fazla bayt tasarrufu sağlar.