Bölüm 10: Arama Ağaçları
Giriş
Öğrenme Çıktıları
Arama, ekleme ve silme işlemlerini ikili arama ağacında uygulamak.
Ağaç yüksekliğinin işlem maliyetlerine etkisini açıklamak.
AVL dönüşlerini ve kırmızı-siyah ağaç kurallarını yorumlamak.
BST, AVL, kırmızı-siyah ve splay ağaçlarını kullanım amacına göre seçmek.
Arama Ağaçları
Arama Ağacı (Search Tree)
- Her düğüm bir öğeyi temsil eder; her öğenin bir anahtarı (key) vardır.
- Öğeler anahtarlarına göre sıralı bir düzende saklanır.
- Arama, kökten başlayıp her düğümde tek bir dala inerek yapılır.
- Maliyet, ağacın yüksekliği h ile orantılıdır: O(h).
- n düğümlü ağaçta h, en iyi ≈ log2 n, en kötü n − 1 olur.
Arama Ağaçları
Temel İşlemler
Ek olarak: en küçük / en büyük anahtar, bir anahtarın ardılı / öncülü, aralık sorguları. Hepsi O(h).
Arama Ağaçları
Arama Ağacı Türleri
B-ağaçları ve B+ ağaçları (çok yollu arama ağaçları) Bölüm 7'de ele alındı.
Arama Ağaçları
İkili Arama Ağacı (Binary Search Tree)
Her düğüm x için: sol alt ağaçtaki tüm anahtarlar < x.anahtar < sağ alt ağaçtaki tüm anahtarlar.
- Özellik yalnızca çocuklar için değil, bütün alt ağaç için geçerlidir: sağdaki ağaçta 7 > 4 doğru, ama 7, 6'nın solunda olamaz.
- Tekrarlayan anahtarlar ya reddedilir ya da tutarlı biçimde tek tarafa (ör. sağa) konur.
Arama Ağaçları
En Küçük, En Büyük ve Sıralı Gezinme
1 2 3 4 6 8// Ön koşul: dugum != null IkiliAgacDugum<E> minDeger( IkiliAgacDugum<E> dugum) { while (dugum.solCocuk != null) dugum = dugum.solCocuk; // sola in return dugum; // en küçük } // maxDeger: aynısı, sagCocuk ile void inorder(IkiliAgacDugum<E> d) { if (d == null) return; inorder(d.solCocuk); // sol System.out.print(d.veri + " "); inorder(d.sagCocuk); // sağ }
Arama Ağaçları
Ağaç Düğümü Yapısı
class AgacDugumu { int veri; AgacDugumu sol, sag; AgacDugumu(int veri) { this.veri = veri; this.sol = null; this.sag = null; } }
class IkiliAgacDugum<E extends Comparable<E>> { E veri; // nesne IkiliAgacDugum<E> solCocuk; // sol çocuk IkiliAgacDugum<E> sagCocuk; // sağ çocuk IkiliAgacDugum(E veri) { this.veri = veri; // çocuklar başlangıçta null } }
Anahtarlar compareTo ile karşılaştırılır; bu yüzden E, Comparable<E> olmalıdır.
BST İşlemleri
Öğe Arama
- Kökten başla; anahtar eşitse bulundu.
- Küçükse sol, büyükse sağ alt ağaçta devam et.
- null'a ulaşırsan anahtar ağaçta yoktur.
boolean ara(IkiliAgacDugum<E> kok, E veri) { if (kok == null) return false; // yok int k = veri.compareTo(kok.veri); if (k == 0) return true; // bulundu else if (k < 0) return ara(kok.solCocuk, veri); else return ara(kok.sagCocuk, veri); }
== ile değil compareTo (veya equals) ile karşılaştır: == yalnızca referansların aynı olup olmadığına bakar.BST İşlemleri
Arama Adım Adım: 5 ve 10
ara(kök, 5): 6 ≠ 5 ve 5 < 6 → satır 7: sol alt ağaçta aramaya devam.
Yeni çağrı ara(4, 5): 5 > 4 → satır 9: sağ alt ağaç.
ara(5, 5): kok.veri == anahtar → satır 4: düğüm 5 döndürülür.
Her çağrı sonucu return ile yukarı iletir. 3 düğüm ziyaret edildi = derinlik + 1.
Şimdi ara(kök, 10): 10 > 6 → satır 9: sağ alt ağaç.
ara(8, 10): 10 > 8 → yine sağ.
ara(9, 10): 10 > 9 → sağ; ama 9'un sağ çocuğu yok (null).
ara(null, 10): kok == null → satır 4: null döndürülür.
null tüm çağrılardan geri iletilir: 10 ağaçta yok. En fazla h + 1 düğüm ziyaret edilir → O(h).
BST İşlemleri
Öğe Ekleme
- Aranıyormuş gibi in; düştüğün null konuma yeni yaprak olarak ekle.
- Yeni düğüm her zaman yaprak olur; O(h).
IkiliAgacDugum<E> ekle(
IkiliAgacDugum<E> kok, E veri) {
if (kok == null)
return new IkiliAgacDugum<>(veri);
int k = veri.compareTo(kok.veri);
if (k < 0)
kok.solCocuk = ekle(kok.solCocuk, veri);
else if (k > 0)
kok.sagCocuk = ekle(kok.sagCocuk, veri);
// k == 0: anahtar zaten var, eklenmez
return kok;
}
// kullanım: kok = ekle(kok, 5);BST İşlemleri
Ekleme Adım Adım: 5, 3, 7, 1
Ağaç boş. kok = ekle(null, 5): satır 3'teki koşul doğru.
Satır 4–5: yeni düğüm 5 oluşturulur ve döndürülür → kök artık 5.
ekle(5, 3): 3 < 5 → satır 8: ekle(kok.sol, 3) çağrılır.
Yeni çağrıda kok = null (5'in solu) → satır 3 koşulu doğru.
Satır 4–5: yeni düğüm 3 oluşturulur ve çağırana döndürülür (henüz bağlı değil).
Geri dönüş: satır 8'de kok.sol = 3 atanır; satır 11: kök 5 döndürülür.
ekle(5, 7): 7 ≥ 5 → satır 10: sağda ekle(null, 7); kok == null.
Yeni düğüm 7 döner, kok.sag'a bağlanır; kök 5 döndürülür.
ekle(5, 1): 1 < 5 → sola; ekle(3, 1): 1 < 3 → yine sola (satır 8).
Üçüncü çağrı: kok == null (3'ün solu) → yeni düğüm 1 oluşturulacak.
Geri dönüşte 3.sol = 1, sonra 5.sol = 3 atanır (değişmeyen bağ yeniden yazılır); kök 5 döner.
BST İşlemleri
Öğe Silme: Üç Durum
Önce silinecek düğüm aranır (O(h)). Sonra çocuk sayısına göre:
null yapılır.sil 70Örnek ağaç (sonraki slaytlarda her silme bu ağaçtan başlar)
BST İşlemleri
Silme: Yaprak ve Tek Çocuk
Yaprak: 70'in çocuğu yok. Ebeveyni 60'ın sağ bağı null yapılır.
70 silindi; ağacın geri kalanı değişmedi.
Tek çocuk (sol): 45'in yalnızca sol çocuğu 42 var. (Orijinal ağaçtan başlıyoruz.)
42, 45'in yerine 40'ın sağ çocuğu olur: ebeveyn doğrudan toruna bağlanır.
Tek çocuk (sağ): 60'ın yalnızca sağ çocuğu 70 var.
70, 60'ın yerine 50'nin sağ çocuğu olur. Sıralama düzeni korunur.
BST İşlemleri
Silme: İki Çocuklu Düğüm
İki çocuk: 40'ın hem solu (30) hem sağı (45) var; doğrudan çıkarılamaz.
İnorder ardıl = sağ alt ağacın en küçüğü: 45'e geç, sonra hep sola → 42.
Ardılın değeri (42), 40'ın düğümüne kopyalanır. Şimdi eski 42 fazladan duruyor.
Sağ alt ağaçtan eski 42 silinir; ardılın sol çocuğu olmadığı için bu hep Durum 1 veya 2'dir.
Alternatif: inorder öncül (sol alt ağacın en büyüğü = 30) kullanılabilir. İkisi de geçerli BST verir.
BST İşlemleri
Silme Kodu
IkiliAgacDugum<E> sil(IkiliAgacDugum<E> kok, E veri) {
if (kok == null) return null; // anahtar yok
int k = veri.compareTo(kok.veri);
if (k < 0)
kok.solCocuk = sil(kok.solCocuk, veri); // solda ara
else if (k > 0)
kok.sagCocuk = sil(kok.sagCocuk, veri); // sağda ara
else if (kok.solCocuk != null && kok.sagCocuk != null) { // iki çocuk
kok.veri = minDeger(kok.sagCocuk).veri; // ardılın değerini kopyala
kok.sagCocuk = sil(kok.sagCocuk, kok.veri); // ardılı sağdan sil
}
else if (kok.solCocuk == null)
return kok.sagCocuk; // yaprak (null döner) ya da yalnız sağ çocuk
else
return kok.solCocuk; // yalnız sol çocuk
return kok;
}kok = sil(kok, 40); (kök silinirse yeni kök bu atamayla güncellenir).BST İşlemleri
İkili Arama Ağacı İşlemlerinin Analizi
- Arama, ekleme ve silmenin maliyeti, erişilen en derin düğümün derinliğiyle orantılıdır: O(h).
| Durum | Yükseklik h | Arama / Ekleme / Silme | n = 106 için adım |
|---|---|---|---|
| Dengeli (en iyi) | ≈ log2 n | O(log n) | ≈ 20 |
| Rastgele sıra (ortalama) | ≈ 1,39 log2 n | O(log n) | ≈ 28 |
| Devrik (en kötü, sıralı girdi) | n − 1 | O(n) | 106 |
BST İşlemleri
Uygulama: Öğrenci Kayıtları
Anahtar olarak öğrenci numarası kullanılır; düğüm, öğrenci nesnesinin tamamını taşır.
public class Ogrenci { int ogrenciNo; // anahtar String adSoyad; public Ogrenci(int ogrenciNo, String adSoyad) { this.ogrenciNo = ogrenciNo; this.adSoyad = adSoyad; } }
public class OgrenciDugum { Ogrenci ogr; // veri OgrenciDugum solCocuk; OgrenciDugum sagCocuk; public OgrenciDugum(Ogrenci ogr) { this.ogr = ogr; // çocuklar başlangıçta null } }
TreeMap<Integer, Ogrenci> ile hazır gelir: anahtar → değer eşlemesi, içeride dengeli bir arama ağacı (kırmızı-siyah).BST İşlemleri
Öğrenci Ekleme ve Arama
OgrenciDugum ekle(OgrenciDugum kok, Ogrenci ogr) {
if (kok == null) return new OgrenciDugum(ogr);
if (ogr.ogrenciNo < kok.ogr.ogrenciNo)
kok.solCocuk = ekle(kok.solCocuk, ogr); // soldan devam
else if (ogr.ogrenciNo > kok.ogr.ogrenciNo)
kok.sagCocuk = ekle(kok.sagCocuk, ogr); // sağdan devam
return kok; // aynı numara eklenmez
}Ogrenci ara(OgrenciDugum kok, int numara) { if (kok == null) return null; // kayıt yok if (numara == kok.ogr.ogrenciNo) return kok.ogr; // bulundu if (numara < kok.ogr.ogrenciNo) return ara(kok.solCocuk, numara); // soldan devam return ara(kok.sagCocuk, numara); // sağdan devam }
ara, boolean yerine öğrenci nesnesini döndürür: bulunursa ad-soyad gibi bilgilere de erişilir. int anahtar olduğu için == ve < doğrudan kullanılabilir.
Denge ve AVL
Denge İhtiyacı
- BST'nin şekli ekleme sırasına bağlıdır: 1, 2, 3, 4 sırayla eklenirse ağaç bir bağlı listeye dönüşür.
- Aynı anahtarlar, farklı yapılarla daha kısa bir ağaçta tutulabilir (sağda iki seçenek).
Denge ve AVL
Dengeleme Örneği
Soldaki ağaçta 9 → 14 → 12 ve 76 → 54 → 72 → 67 kolları uzamış. Bu alt ağaçlar yeniden düzenlenince (turuncu yeni alt ağaç kökleri) aynı 11 anahtar daha kısa bir ağaçta durur:
- Yeniden düzenleme sırasında inorder sıra değişmez: 9 12 14 17 19 23 50 54 67 72 76.
- Ağacı her seferinde baştan kurmak O(n) olurdu; AVL ve kırmızı-siyah ağaçlar bunu yalnızca eklenen/silinen yol üzerinde, O(log n) sürede yapar.
Denge ve AVL
AVL Ağacı
- Adelson-Velsky ve Landis (1962): ilk dengeli BST.
- Denge faktörü: bf(x) = h(sol) − h(sağ). Boş alt ağacın yüksekliği −1.
- AVL koşulu: her düğümde bf ∈ {−1, 0, +1}.
- Sonuç: h < 1,44 log2(n + 2) → tüm işlemler O(log n).
- Her düğüm yüksekliğini saklar; ekleme/silmeden sonra kökte doğru yukarı çıkılırken bf kontrol edilir.
Denge ve AVL
Döndürme (Rotation)
Sağa döndürme (sol ağır y): x yukarı çıkar, y x'in sağ çocuğu olur; x'in sağ alt ağacı T2, y'nin soluna geçer.
Sola döndürme (sağ ağır x): simetrik. Yalnızca 3 bağ değişir (kalın çizgiler) → O(1).
Denge ve AVL
Dört Dengesizlik Durumu
LL durumunda sağa, RR durumunda sola tek dönüş yapılır.
Denge ve AVL
Çift Dönüşler: LR ve RL
LR: önce sola, sonra sağa. RL: önce sağa, sonra sola dönüş yapılır.
Denge ve AVL
AVL Ekleme Örneği: 10, 20, 30, 40, 50, 25
10 kök olur. Tek düğümün bf'si 0.
20 > 10 → sağa. bf(10) = −1 − 0 = −1: hâlâ AVL.
30 → 10'un sağındaki 20'nin sağına. bf(10) = −2 ✗ — sağ-sağ: RR durumu.
10'da sola döndürme: 20 kök olur, 10 onun sol çocuğu. Tüm bf = 0.
40 → 20'nin sağı → 30'un sağı. bf(30) = −1, bf(20) = −1: denge bozulmadı.
50 eklenince bf(30) = −2 ve bf(20) = −2. En alttaki dengesiz düğüm 30 → RR.
30'da sola döndürme: 40 yukarı çıkar, 30 onun sol çocuğu olur. bf(20) = −1.
25 → 20'nin sağı, 40'ın solu, 30'un solu. bf(20) = −2 ✗; sağ çocuk 40 sol ağır (+1) → RL durumu.
RL, 1. döndürme: 40'ta sağa döndür → üçgen düz çizgiye (sağ-sağ) dönüşür. 20 hâlâ −2.
RL, 2. döndürme: 20'de sola döndür → 30 kök olur; 25, 20'nin sağına geçer. Ağaç yeniden AVL.
Denge ve AVL
AVL Döndürme ve Dengeleme Kodu
int h(AvlDugum d) { return d == null ? -1 : d.yukseklik; } int bf(AvlDugum d) { return h(d.sol) - h(d.sag); } void guncelle(AvlDugum d) { d.yukseklik = 1 + Math.max(h(d.sol), h(d.sag)); } AvlDugum sagaDondur(AvlDugum y) { AvlDugum x = y.sol; y.sol = x.sag; // T2 → y.sol x.sag = y; // y → x.sag guncelle(y); // önce alttaki guncelle(x); return x; // yeni kök }
AvlDugum dengele(AvlDugum d) {
guncelle(d);
if (bf(d) > 1) { // sol ağır
if (bf(d.sol) < 0) // LR
d.sol = solaDondur(d.sol);
return sagaDondur(d); // LL
}
if (bf(d) < -1) { // sağ ağır
if (bf(d.sag) > 0) // RL
d.sag = sagaDondur(d.sag);
return solaDondur(d); // RR
}
return d;
}
// solaDondur: sol ↔ sag simetriği
// ekle/sil BST gibi; dönüşte:
// return dengele(kok);Özyineleme geri dönerken yol üzerindeki her düğümde dengele çağrılır; silmede birden fazla düğümde döndürme gerekebilir (en fazla O(log n)).
Kırmızı-Siyah Ağaçlar
Kırmızı-Siyah Ağaç (Red-Black Tree)
- Her düğüm kırmızı ya da siyahtır.
- Kök siyahtır.
- Tüm yapraklar (NIL, boş çocuklar) siyah kabul edilir.
- Kırmızı düğümün çocukları siyahtır: ardışık iki kırmızı olmaz.
- Bir düğümden NIL yapraklara giden her yolda aynı sayıda siyah düğüm vardır (siyah yükseklik).
Örnek: kökten her NIL'e giden yolda 2 siyah düğüm var (kök dahil, NIL hariç)
Kırmızı-Siyah Ağaçlar
Kurallar Neden Dengeyi Garanti Eder?
TreeMap/TreeSet ve C++ std::map bu yapıyı kullanır.Kırmızı-Siyah Ağaçlar
Kırmızı-Siyah Ağaca Ekleme
Yeni düğüm BST gibi eklenir ve kırmızı boyanır (siyah yükseklik bozulmasın diye). Ebeveyn de kırmızıysa kural 4 bozulur; amcaya (ebeveynin kardeşi) bakılır:
- Ebeveyn siyahsa hiçbir şey yapılmaz. En sonda kök her zaman siyaha boyanır.
- NIL amca siyah sayılır.
- Silme benzer ama daha çok durumludur ("çift siyah" düzeltmesi); bu derste ayrıntısına girmiyoruz.
Kırmızı-Siyah Ağaçlar
Kırmızı-Siyah Ekleme: 10, 20, 30, 15
10 eklenir (kırmızı); kök olduğu için siyaha boyanır.
20 → 10'un sağına, kırmızı. Ebeveyn siyah: kural bozulmadı.
30 → 20'nin sağına, kırmızı: 20–30 ardışık kırmızı. Amca (10'un solu) NIL = siyah; 10–20–30 düz çizgi.
Çizgi durumu: dede 10'da sola döndür, renkleri değiştir: 20 siyah, 10 kırmızı.
15 → 20'nin solu, 10'un sağı; kırmızı. Ebeveyn 10 kırmızı ✗, amca 30 kırmızı.
Renk değiştir: ebeveyn 10 ve amca 30 siyah, dede 20 kırmızı. Ama 20 kök ✗.
Kök yeniden siyaha boyanır; siyah yükseklik bir artar. Tüm kurallar sağlanır.
Kırmızı-Siyah Ağaçlar
Kırmızı-Siyah Ekleme: 12 ve 5
Önceki ağaçtan devam: sırada 12 ve 5 var.
12 → 20'nin solu, 10'un sağı, 15'in solu. 15–12 ardışık kırmızı; amca (10'un solu) NIL = siyah; 10–15–12 üçgen.
Üçgen → çizgi: ebeveyn 15'te sağa döndür. Şimdi 10–12–15 düz çizgi (hâlâ ardışık kırmızı).
Çizgi: dede 10'da sola döndür; 12 siyah, 10 kırmızı olur. Kurallar sağlandı.
5 → 20 → 12 → 10'un solu, kırmızı. Ebeveyn 10 kırmızı ✗; amca 15 kırmızı.
Renk değiştir: 10 ve 15 siyah, dede 12 kırmızı. 12'nin ebeveyni 20 siyah → bitti, döndürme gerekmedi.
Kırmızı-Siyah Ağaçlar
AVL mi, Kırmızı-Siyah mı?
| Özellik | AVL | Kırmızı-Siyah |
|---|---|---|
| Denge ölçütü | |bf| ≤ 1 her düğümde | renk kuralları, eşit siyah yükseklik |
| En büyük yükseklik | ≈ 1,44 log2 n | 2 log2(n + 1) |
| Arama | O(log n), biraz daha hızlı (daha kısa) | O(log n) |
| Ekleme döndürmesi | en fazla 1 (tek veya çift) | en fazla 2 |
| Silme döndürmesi | O(log n) olabilir | en fazla 3 |
| Düğümde ek bilgi | yükseklik (veya bf) | 1 bit renk |
| Tercih | aramanın baskın olduğu işler | sık ekleme/silme, kütüphaneler |
Splay Ağaçları
Splay Ağacı (Splay Tree)
- Sleator ve Tarjan (1985): kendini düzenleyen (self-adjusting) BST.
- Her erişimde (arama, ekleme, silme) ilgili düğüm döndürmelerle köke taşınır: splay işlemi.
- Düğümlerde denge bilgisi (yükseklik, renk) tutulmaz.
- Tek bir işlem O(n) sürebilir; ama m işlemlik her dizi O(m log n) sürer: amortize O(log n).
Splay Ağaçları
Splay Adımları: Zig, Zig-Zig, Zig-Zag
x: splay edilen düğüm, p: ebeveyni, g: dedesi. x kök olana kadar bu adımlar tekrarlanır.
Zig: x'in ebeveyni p köktür → p'de tek döndürme. (Yalnızca son adımda olabilir.)
Zig-zig: x ve p aynı yönde çocuk → önce g'de, sonra p'de döndür. (AVL'deki tek döndürmeden farklı!)
Zig-zag: x ve p zıt yönde → önce p'de, sonra g'de döndür (AVL çift döndürmesiyle aynı).
Splay Ağaçları
Splay Örneği: splay(50), sonra splay(10)
splay(50): önce normal BST araması: 80 → 40 → 60 → 50.
x = 50 sol, p = 60 sağ çocuk → zig-zag. Önce p = 60'ta sağa döndür.
Sonra g = 40'ta sola döndür: 50, 40 ile 60'ın ebeveyni olur.
50'nin ebeveyni 80 kök → zig: 80'de sağa döndür. 50 artık kök; 60, 80'in soluna geçti.
Şimdi splay(10): yol 50 → 40 → 20 → 10. x = 10, p = 20, g = 40 hepsi sol → zig-zig.
Zig-zig, önce dede: g = 40'ta sağa döndür (20 yukarı, 30 → 40'ın soluna).
Sonra ebeveyn: p = 20'de sağa döndür. 10 yukarı çıktı.
Zig: kök 50'de sağa döndür → 10 kök. Yakın zamanda erişilen 50 hâlâ köke yakın (derinlik 1).
Özet
Özet: Arama Ağaçlarında İşlem Maliyetleri
| Yapı | Yükseklik | Arama | Ekleme | Silme | Nasıl dengelenir? |
|---|---|---|---|---|---|
| BST | log n … n | O(h) | O(h) | O(h) | dengelenmez; en kötü O(n) |
| AVL | ≤ 1,44 log n | O(log n) | O(log n) | O(log n) | bf ∈ {−1, 0, 1}; LL, RR, LR, RL döndürmeleri |
| Kırmızı-Siyah | ≤ 2 log(n+1) | O(log n) | O(log n) | O(log n) | renk değiştirme + en çok 2–3 döndürme |
| Splay | sınırsız | O(log n)* | O(log n)* | O(log n)* | erişilen düğüm zig / zig-zig / zig-zag ile köke |
* Amortize; tek işlem O(n) olabilir. Tüm yapılarda inorder gezinme O(n) ve anahtarları sıralı verir; min/max O(h).
Özet
Etkileşimli Simülatörler
Kendi anahtarlarınızla deneyin: ekleyin, silin, döndürmeleri adım adım izleyin.
Özet
Örnek Problemler
- Boş BST'ye 50, 30, 70, 20, 40, 60, 80 sırayla eklenir. Yükseklik nedir? Inorder çıktı nedir?
- Aynı anahtarlar 20, 30, 40, 50, 60, 70, 80 sırasıyla eklenirse yükseklik ve arama maliyeti ne olur?
- 1. sorudaki ağaçtan kök 50, inorder ardıl kullanılarak silinirse ağaç nasıl olur?
- Boş AVL ağacına 3, 2, 1 eklenir. Hangi durum oluşur, hangi döndürme yapılır?
- Boş AVL ağacına 10, 30, 20 eklenir. Hangi durum oluşur, sonuç ağaç nedir?
- Kırmızı-siyah ağaçta kökten NIL'e giden en uzun yol, en kısa yolun en fazla kaç katıdır? Neden?
- Splay ağacında zig-zig adımında döndürmeler hangi sırayla yapılır?
Cevapları göster
- h = 2 (tam dengeli); inorder: 20 30 40 50 60 70 80.
- Sağa doğru zincir: h = 6; arama O(n) (en kötü 7 karşılaştırma).
- Ardıl 60 köke kopyalanır, 70'in solundaki 60 silinir: 60(30(20, 40), 70(—, 80)).
- 3'te bf = 2, sol çocuk 2'de bf = 1 → LL; 3'te sağa döndürme → 2(1, 3).
- 10'da bf = −2, sağ çocuk 30'da bf = +1 → RL; 30'da sağa, 10'da sola → 20(10, 30).
- 2 katı: siyah sayısı her yolda eşit ve kırmızılar ardışık olamaz.
- Önce dede (g), sonra ebeveyn (p) döndürülür.
Özet
Kaynaklar
- Goodrich, Tamassia ve Goldwasser, Data Structures and Algorithms in Java, 6. baskı, 2014.
- Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, 2022.
- Sedgewick ve Wayne, Algorithms, 4. baskı, 2011.
Son
← → veya boşluk ile gezinin · F: tam ekran · Home/End: ilk/son slayt