SEN2212 · 3. hafta · Introduction to binary search trees.

İ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.

binary search tree (BST)BST propertysearch pathinsertdeleteleafinorder successorinorder predecessorfindMinfindMaxdegenerate treebalanced tree

Sıralı bir dizide ikili arama (binary search) O(log⁡n)O(\log n) sürer, ama ekleme ve silme elemanları kaydırdığı için O(n)O(n). Bağlı listede ekleme kolay, ama arama O(n)O(n). İ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 O(log⁡n)O(\log n).

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: O(h)O(h).

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 O(n)O(n). Sağdaki mükemmel dengeli, arama O(log⁡n)O(\log n). 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, 70 sı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üçüğü.

  1. Sağ alt ağaçta hep sola in, en küçüğü bul.
  2. O değeri silinecek düğüme kopyala.
  3. 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:

  1. x’in sağ alt ağacı varsa: o alt ağacın minimumu. Ana ağaçta successor(30) = 35.
  2. 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

İşlemMaliyetEn iyi / ortalamaEn kötü
find, containsO(h)O(h)O(log⁡n)O(\log n)O(n)O(n)
insertO(h)O(h)O(log⁡n)O(\log n)O(n)O(n)
removeO(h)O(h)O(log⁡n)O(\log n)O(n)O(n)
findMin, findMaxO(h)O(h)O(log⁡n)O(\log n)O(n)O(n)
inorder (tüm ağaç)O(n)O(n)O(n)O(n)O(n)O(n)

n düğümlü ağacın yüksekliği ⌊log⁡2n⌋\lfloor \log_2 n \rfloor ile n−1n - 1 arasında. Anahtarlar rastgele sırayla eklenirse ortalama derinlik yaklaşık 1.39log⁡2n1.39 \log_2 n, yani beklenen maliyet O(log⁡n)O(\log n). 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üşünceDoğrusu
BST’yi sadece ebeveyn-çocuk ilişkisiyle kontrol etmekKural tüm alt ağaç için; (min, max) aralığı taşı
Ekleme mevcut düğümleri yeniden düzenlerDüz BST’de yeni anahtar hep yaprak olur
İki çocuklu silmede sol alt ağacın min’ini almakSağ alt ağacın min’i (successor) ya da sol alt ağacın max’ı (predecessor)
Successor hep sağ çocukturSağ alt ağacın EN SOLUNDAKİ düğüm; sağ çocuğun solu olabilir
Sağ alt ağaç yoksa successor yokturYukarıda, sol tarafından geldiğin ilk ata olabilir
BST işlemleri her zaman O(log⁡n)O(\log n)O(h)O(h); en kötü O(n)O(n)
Sıralı girdi BST’yi dengeli yaparTam tersi: zincir üretir
Başarısız arama hiç iş yapmazYaprağa kadar iner, yine O(h)O(h)

Kendini test et

Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.

Soru 1kolay

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
Level-order: 45 22 67 10 30 55 80 27 60; height 3

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       60
En derin düğümler 27 ve 60, derinlik 3. Yükseklik 3.

Soru 2kolay

In the BST from question 1, which keys are compared when searching for 58, and how many comparisons are made?

Cevabı göster
45, 67, 55, 60; 4 comparisons, not found

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.

Soru 3orta

In the BST from question 1, what are the inorder successor of 22 and the inorder successor of 30?

Cevabı göster
27 and 45

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.

Soru 4kolay

Starting from the BST in question 1, delete 30 (one child). Give the level-order traversal of the result.

Cevabı göster
45 22 67 10 27 55 80 60

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
              \
               60
Level-order: 45 22 67 10 27 55 80 60.

Soru 5orta

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
Root 55; level-order 55 22 67 10 30 60 80 27

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
        /
      27
Level-order: 55 22 67 10 30 60 80 27.

Soru 6orta

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
55 27 10 30 67 60 80

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   80
Preorder: 55 27 10 30 67 60 80. Ağacın yüksekliği 2'ye düştü.

Soru 7kolay

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
Height 6; 7 comparisons

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).

Soru 8orta

Give an insertion order of the keys 1 to 7 that produces a perfectly balanced BST of height 2.

Cevabı göster
4 2 6 1 3 5 7 (any order where 4 is first and 2 comes before 1, 3 and 6 before 5, 7)

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.

Soru 9orta

A BST has preorder traversal 40 25 10 30 60 50 70. What is its postorder traversal?

Cevabı göster
10 30 25 50 70 60 40

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.

Soru 10orta

Is the binary tree below a valid BST? Explain.

        50
       /  \
     30    70
    /  \   /
  20   55 60
Cevabı göster
No; 55 is in the left subtree of 50 but 55 > 50

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.

Soru 11zor

How many structurally different BSTs can be formed with the keys 1, 2, 3? With 1, 2, 3, 4?

Cevabı göster
5 and 14

Kökü seç, solu ve sağı bağımsız kur. Cn=∑k=1nCk−1Cn−kC_n = \sum_{k=1}^{n} C_{k-1} C_{n-k}, C0=1C_0 = 1.C1=1C_1 = 1, C2=2C_2 = 2, C3=C0C2+C1C1+C2C0=2+1+2=5C_3 = C_0C_2 + C_1C_1 + C_2C_0 = 2 + 1 + 2 = 5.C4=C0C3+C1C2+C2C1+C3C0=5+2+2+5=14C_4 = C_0C_3 + C_1C_2 + C_2C_1 + C_3C_0 = 5 + 2 + 2 + 5 = 14. 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.

Soru 12kolay

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
Worst O(n), average O(log n); cost is O(h), the height

Üç 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 1.39log⁡2n1.39 \log_2 n: 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).

Deftere not kartı

BST özelliği: sol alt ağaçtaki HER anahtar < düğüm < sağ alt ağaçtaki HER anahtar. Inorder gezinme = sıralı liste. Ağacı doğrulamak: inorder artan mı, ya da (min,max) aralığı taşı. Arama: küçükse sola, büyükse sağa, null'a düşersen yok. Ekleme: aramanın düştüğü null'a yeni yaprak. findMin: hep sola. findMax: hep sağa. Silme 1: yaprak → direkt kaldır. Silme 2: tek çocuk → çocuk yerine geçer. Silme 3: iki çocuk → sağ alt ağacın min'ini (inorder successor) kopyala, onu sağdan sil. Successor: sağ alt ağaç varsa onun min'i; yoksa sol tarafından geldiğin ilk ata. Maliyet O(h). Rastgele sıra: h ~ O(log n). Sıralı sıra: h = n-1, bağlı liste. Ekleme sırası şekli belirler; aynı anahtarlar, farklı sıra, farklı ağaç. Farklı BST sayısı (Catalan): 1, 1, 2, 5, 14, 42. Tekrar eden anahtar: bu derste yok sayılır (ekleme bir şey yapmaz).