İkili arama ağaçları: arama, ekleme, silme
BST özelliği, arama yolu, ekleme sırasının ağacın şeklini nasıl belirlediği, silmenin üç durumu, inorder successor ve yükseklik analizi.
Sıralı bir dizide ikili arama (binary search) sürer, ama ekleme ve silme elemanları kaydırdığı için . Bağlı listede ekleme kolay, ama arama . İkili arama ağacı (binary search tree, BST) ikisinin iyi tarafını birleştirmeye çalışır: ağaç alçak kaldıkça arama, ekleme ve silme .
Sınavda bu konudan neredeyse kesin gelen sorular: verilen sırayla ekle, ağacı çiz, şu düğümü sil, yeni ağacı çiz, arama yolunu yaz, bu ağaç BST mi, en kötü durum ne. Hepsi aşağıdaki birkaç kurala dayanıyor.
BST özelliği
Her düğüm x için:
- x’in sol alt ağacındaki her anahtar x’ten küçük,
- x’in sağ alt ağacındaki her anahtar x’ten büyük.
Bu derste anahtarlar tekrar etmez. Bu özellikten çıkan en önemli sonuç: inorder gezinme anahtarları artan sırada verir.
Bütün sayfa boyunca bu ağacı kullanacağız. Boş ağaca 50, 30, 70, 20, 40, 60, 80, 35, 45, 65 sırasıyla eklendi:
50
/ \
30 70
/ \ / \
20 40 60 80
/ \ \
35 45 65
Inorder: 20 30 35 40 45 50 60 65 70 80. Sıralı, demek ki BST.
Arama (find / contains)
Kökten başla. Aranan anahtar düğümden küçükse sola, büyükse sağa git, eşitse bulundu. null’a düşersen yok.
find 45: 50 30 40 45 bulundu, 4 karş.
find 63: 50 70 60 65 null yok, 4 karş.
Her adımda bir seviye iniyorsun, yani maliyet en fazla yükseklik + 1 karşılaştırma: .
findMin hep sola gider (20), findMax hep sağa gider (80). Karşılaştırma bile gerekmez.
Ekleme (insert)
Yeni anahtarı arar gibi in. Arama null’a düştüğü yerde yeni bir yaprak oluştur. Ekleme hiçbir zaman mevcut düğümleri yerinden oynatmaz.
Yukarıdaki ağaca 63 eklenirse: 50 → 70 → 60 → 65 → 65’in solu boş, 63 oraya girer.
Ekleme sırası şekli belirler
Aynı anahtar kümesi, farklı sıralarla çok farklı ağaçlar verir:
1 2 3 4 5 6 7 sırası: 4 2 6 1 3 5 7 sırası:
1 4
\ / \
2 2 6
\ / \ / \
3 1 3 5 7
\
...7 (yükseklik 6) (yükseklik 2)
Soldaki ağaç aslında bir bağlı liste (degenerate tree). Arama . Sağdaki mükemmel dengeli, arama . Sıralı veri eklemek gerçek hayatta çok yaygın (zaman damgaları, artan ID’ler), bu yüzden düz BST’ye güvenmek risklidir.
TUZAK · “zigzag” girdiler de kötüdür.
10, 90, 20, 80, 30, 70sıralı değil ama her eleman bir öncekinin tek çocuğu olur. Sonuç yine zincir, yükseklik 5. Kötü ağaç için sıralı girdi şart değil.
Silme (remove): üç durum
Silinecek düğümü önce arayarak bul. Sonra çocuk sayısına bak. Aşağıdaki üç örneğin her biri orijinal ağaçtan başlıyor.
Durum 1: yaprak
Ebeveynin ilgili referansını null yap. 20’yi silmek: 30’un solu null olur. Başka hiçbir şey değişmez.
Durum 2: tek çocuk
Düğümü atla: ebeveyni doğrudan torunu göstersin. 60’ın tek çocuğu 65. 60 silinince 70’in solu 65 olur.
önce: 70 sonra: 70
/ \ / \
60 80 65 80
\
65
BST özelliği bozulmaz: 65 zaten 70’in sol alt ağacındaydı, orada kalıyor.
Durum 3: iki çocuk
Düğümü doğrudan kaldıramazsın, iki alt ağacı tek bir ebeveyn referansına bağlayamazsın. Çözüm: düğümün değerini, sıralamada ona en yakın değerle değiştir. Bu derste kullanılan kural: inorder successor, yani sağ alt ağacın en küçüğü.
- Sağ alt ağaçta hep sola in, en küçüğü bul.
- O değeri silinecek düğüme kopyala.
- O değeri sağ alt ağaçtan sil. Sağ alt ağacın minimumunun sol çocuğu olamaz, bu yüzden bu ikinci silme hep durum 1 ya da 2’dir.
30’u silelim. 30’un iki çocuğu var (20 ve 40). Sağ alt ağacı (40, 35, 45), en küçüğü 35. 35 yukarı kopyalanır, 35 yaprağı silinir:
50
/ \
35 70
/ \ / \
20 40 60 80
\ \
45 65
Program çıktısı: 50(35(20,40(-,45)),70(60(-,65),80)).
Şimdi orijinal ağaçta kökü (50) silelim. Sağ alt ağacın en küçüğü: 70 → 60, 60’ın solu yok, successor 60. 60 köke kopyalanır. Eski 60’ın tek çocuğu 65 olduğu için ikinci silme durum 2: 65, 70’in sol çocuğu olur.
60
/ \
30 70
/ \ / \
20 40 65 80
/ \
35 45
İPUCU · predecessor de olur. Sol alt ağacın en büyüğü (inorder predecessor) ile de silme doğru çalışır. Sınavda hangi kural istendiği yazmıyorsa successor kullan ve bunu cevabına not düş.
Inorder successor
x’ten büyük en küçük anahtar. İki durum:
- x’in sağ alt ağacı varsa: o alt ağacın minimumu. Ana ağaçta successor(30) = 35.
- Yoksa: yukarı çık; x’e sol tarafından indiğin ilk ata successor. successor(45): 45, 40’ın sağı; 40, 30’un sağı; 30, 50’nin solu. Cevap 50.
Ebeveyn referansı yoksa kökten arayarak bulunur: x’i ararken sola döndüğün her düğümü “aday” olarak kaydet, son aday successor.
static Integer successor(Node root, int x) {
Node t = root, succ = null;
while (t != null) {
if (x < t.element) { succ = t; t = t.left; }
else t = t.right;
}
return succ == null ? null : succ.element;
}
En büyük anahtarın (80) successor’ı yoktur. Predecessor simetriktir: sol alt ağacın maksimumu ya da sağ tarafından geldiğin ilk ata.
Yükseklik ve karmaşıklık
| İşlem | Maliyet | En iyi / ortalama | En kötü |
|---|---|---|---|
| find, contains | |||
| insert | |||
| remove | |||
| findMin, findMax | |||
| inorder (tüm ağaç) |
n düğümlü ağacın yüksekliği ile arasında. Anahtarlar rastgele sırayla eklenirse ortalama derinlik yaklaşık , yani beklenen maliyet . Ama “rastgele” garanti değil. Garanti isteyen 5. ve 6. haftadaki dengeli ağaçlara (AVL, red-black) geçer.
Sık yapılan hatalar
| Yanlış düşünce | Doğrusu |
|---|---|
| BST’yi sadece ebeveyn-çocuk ilişkisiyle kontrol etmek | Kural tüm alt ağaç için; (min, max) aralığı taşı |
| Ekleme mevcut düğümleri yeniden düzenler | Düz BST’de yeni anahtar hep yaprak olur |
| İki çocuklu silmede sol alt ağacın min’ini almak | Sağ alt ağacın min’i (successor) ya da sol alt ağacın max’ı (predecessor) |
| Successor hep sağ çocuktur | Sağ alt ağacın EN SOLUNDAKİ düğüm; sağ çocuğun solu olabilir |
| Sağ alt ağaç yoksa successor yoktur | Yukarıda, sol tarafından geldiğin ilk ata olabilir |
| BST işlemleri her zaman | ; en kötü |
| Sıralı girdi BST’yi dengeli yapar | Tam tersi: zincir üretir |
| Başarısız arama hiç iş yapmaz | Yaprağa kadar iner, yine |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
Insert the keys 45, 22, 67, 10, 30, 55, 80, 27, 60 in this order into an initially empty BST. Give the level-order traversal and the height of the result.
Cevabı göster
45 kök. 22 < 45 sola, 67 sağa. 10: 45'in solu, 22'nin solu. 30: 22'nin sağı. 55: 67'nin solu. 80: 67'nin sağı.
27: 45 → 22 → 30 → 30'un solu. 60: 45 → 67 → 55 → 55'in sağı.
45
/ \
22 67
/ \ / \
10 30 55 80
/ \
27 60En derin düğümler 27 ve 60, derinlik 3. Yükseklik 3.In the BST from question 1, which keys are compared when searching for 58, and how many comparisons are made?
Cevabı göster
58 > 45 sağa, 58 < 67 sola, 58 > 55 sağa, 58 < 60 sola. 60'ın sol çocuğu null: arama başarısız.
4 karşılaştırma. Başarısız arama da bir yaprağın altına kadar iner, maliyeti O(h).
58 eklenseydi tam bu null konuma, 60'ın sol çocuğu olarak girerdi.
In the BST from question 1, what are the inorder successor of 22 and the inorder successor of 30?
Cevabı göster
22'nin sağ alt ağacı var (30, 27): successor o alt ağacın en küçüğü. 30'dan sola in: 27.
30'un sağ alt ağacı yok. O zaman yukarı çık: 30'un ilk "sol tarafından" geldiğin atası successor. 30, 22'nin sağ çocuğu; 22, 45'in sol çocuğu. Cevap 45.
Kontrol: inorder 10 22 27 30 45 55 60 67 80. 22'den sonra 27, 30'dan sonra 45.
Starting from the BST in question 1, delete 30 (one child). Give the level-order traversal of the result.
Cevabı göster
30'un tek çocuğu var (27). Tek çocuklu düğüm silinirken çocuğu onun yerine geçer: 22'nin sağ referansı artık 27'yi gösterir.
45
/ \
22 67
/ \ / \
10 27 55 80
\
60Level-order: 45 22 67 10 27 55 80 60.Starting from the BST in question 1, delete the root 45 using the inorder successor. Give the new root and the level-order traversal.
Cevabı göster
45'in iki çocuğu var. Sağ alt ağacın en küçüğünü bul: 67 → 55, 55'in solu yok, successor 55.
55'i köke kopyala. Sonra 55'i sağ alt ağaçtan sil: 55'in tek çocuğu 60, 60 onun yerine 67'nin sol çocuğu olur.
55
/ \
22 67
/ \ / \
10 30 60 80
/
27Level-order: 55 22 67 10 30 60 80 27.Starting from the BST in question 1, delete 22 and then delete 45 (both with inorder successor). Give the preorder traversal of the result.
Cevabı göster
22'yi sil: iki çocuğu var. Sağ alt ağacın (30, 27) en küçüğü 27. 22'nin yerine 27 yazılır, 27 yaprağı silinir. Artık 27'nin çocukları 10 ve 30.
45'i sil: successor 55 (önceki sorudaki gibi), 60 yukarı çıkar.
55
/ \
27 67
/ \ / \
10 30 60 80Preorder: 55 27 10 30 67 60 80. Ağacın yüksekliği 2'ye düştü.The keys 1 to 7 are inserted in increasing order into an empty BST. What is the height of the tree, and how many comparisons does an unsuccessful search for 8 make?
Cevabı göster
Her yeni anahtar öncekilerin hepsinden büyük, hep sağa gider. Ağaç sağa doğru bir zincire, yani bağlı listeye döner (degenerate tree).
7 düğüm, 6 kenar: yükseklik n - 1 = 6.
8 aranırken 1, 2, ..., 7 sırayla karşılaştırılır: 7 karşılaştırma. Bu BST'nin en kötü durumu: O(n).
Give an insertion order of the keys 1 to 7 that produces a perfectly balanced BST of height 2.
Cevabı göster
Kök ortanca olmalı: 4. Sol alt ağacın kökü {1,2,3}'ün ortancası 2, sağınki {5,6,7}'nin ortancası 6.
Bu ağacın level-order'ı 4 2 6 1 3 5 7, ve bu sıra tam da ağacı üretir.
Şart: her alt ağacın kökü o alt ağaçtaki diğer anahtarlardan önce eklenmeli. Örneğin 4 6 2 7 5 3 1 de aynı ağacı verir.
A BST has preorder traversal 40 25 10 30 60 50 70. What is its postorder traversal?
Cevabı göster
BST'de inorder her zaman sıralı listedir: 10 25 30 40 50 60 70. Yani preorder + (sıralı) inorder elinde.
Daha kısa yol: preorder sırasıyla boş BST'ye ekle, aynı ağaç çıkar. 40 kök, 25 ve 10 sola, 30 25'in sağına, 60 sağa, 50 ve 70 60'ın çocukları.
Postorder: 10 30 25 50 70 60 40.
Is the binary tree below a valid BST? Explain.
50
/ \
30 70
/ \ /
20 55 60Cevabı göster
Her düğüm sadece kendi çocuklarıyla karşılaştırılırsa geçerli görünür: 30 < 55, 20 < 30, 60 < 70.
Ama BST özelliği tüm alt ağaç için geçerli olmalı: 50'nin sol alt ağacındaki her anahtar 50'den küçük olmalı. 55 bu kuralı bozar.
Doğru kontrol her düğüme (min, max) aralığı taşır: 55 için aralık (30, 50), 55 bu aralığın dışında.
How many structurally different BSTs can be formed with the keys 1, 2, 3? With 1, 2, 3, 4?
Cevabı göster
Kökü seç, solu ve sağı bağımsız kur. , ., , .. Bunlar Catalan sayıları.
3 anahtarın 6 ekleme sırası var ama 2 1 3 ile 2 3 1 aynı ağacı verir, bu yüzden 5.
Give the worst-case and the average-case time of search, insert and delete in a BST with n nodes (random insertion order). What determines the cost?
Cevabı göster
Üç işlem de kökten bir yol boyunca iner, yolun uzunluğu en fazla yükseklik h. Maliyet O(h).
Rastgele ekleme sırasında ortalama düğüm derinliği yaklaşık : O(log n).
Sıralı ya da neredeyse sıralı girdi h = n - 1 üretir: O(n). Bu yüzden 5. haftada AVL gibi dengeli ağaçlara geçiyoruz.
Doğrulama: Tüm ekleme dizilerinden çıkan ağaçlar, arama yolları, silme sonrası ağaçlar (iki çocukta inorder successor), successor/predecessor değerleri, yükseklikler ve farklı BST şekli sayıları Java ile hesaplandı (verify/SEN2212/W03.java, java W03.java).