AVL Ağacı Kendini Dengeleyen BST

AVL ağacı denge faktörü hesaplama, LL/RR tek rotasyon, LR/RL çift rotasyon, dengeli ekleme-silme — adım adım görseller, karar tabloları ve C kodu ile anlatım.

🗂️ Veri Yapıları 📅 21 February 2026 👁️ 2 görüntülenme

Neden Dengeleme?

BST'nin Aşil topuğunu hatırlayalım: sıralı veri eklendiğinde ağaç bir zincire (bağlı listeye) dönüşür ve tüm operasyonlar O(n)'e düşer. AVL ağacı bu sorunu her operasyonda otomatik dengeleme yaparak çözer.

Aynı 7 Eleman — BST vs AVL
BST — Sıra: 10,20,30,40,50,60,70
10203040506070
h = 6 → arama O(n) ✗
AVL — Aynı 7 eleman, otomatik dengeli
40206010305070
h = 2 → arama O(log n) ✓
7 eleman: BST'de 6 karşılaştırma, AVL'de en fazla 2 karşılaştırma. Fark n büyüdükçe dramatikleşir.
AVL Ağacı (1962): Georgy Adelson-Velsky ve Evgenii Landis tarafından önerilen ilk kendini dengeleyen ikili arama ağacıdır. Her düğümde sol ve sağ alt ağaç yükseklik farkı en fazla 1 olmalıdır. Bu kural ihlal edildiğinde rotasyon operasyonlarıyla denge yeniden sağlanır.

Denge Faktörü (Balance Factor)

Her düğümün denge faktörü (BF), sol alt ağaç yüksekliğinden sağ alt ağaç yüksekliğinin çıkarılmasıyla hesaplanır:

BF(node) = height(left) − height(right)

BF = -1, 0 veya +1 → dengeli ✓
BF ≤ -2 → sağ-ağır (right-heavy) → sola rotasyon gerekir
BF ≥ +2 → sol-ağır (left-heavy) → sağa rotasyon gerekir

Denge Faktörü Hesaplama — Detaylı Görsel

Her Düğümde Yükseklik (h) ve Denge Faktörü (BF)
40h=2 | BF=020h=1 | BF=060h=1 | BF=010h=0 | BF=030h=0 | BF=050h=0 | BF=070h=0 | BF=0
Tüm düğümlerde BF ∈ {-1, 0, +1} → geçerli AVL ağacı ✓

Şimdi bu ağaca 5 ekleyelim ve ne olduğuna bakalım:

insert(5) → Dengesizlik Oluşumu
40h=3 | BF=+120h=2 | BF=+2 ✗60h=1 | BF=010h=1 | BF=+13050705YENİ
Düğüm 20'de BF = +2 → sol-ağır → dengesizlik! Rotasyon gerekiyor.

4 Dengesizlik Durumu

Dengesizlik her zaman eklenen/silinen düğümden köke doğru yürürken ilk BF ≥ 2 veya BF ≤ -2 olan düğümde tespit edilir. Dengesizliğin yönüne göre 4 durum ve 4 rotasyon türü vardır:

4 Dengesizlik Kalıbı → 4 Rotasyon Türü
LL — Sol-Sol
z (+2) / y / x
→ Sağa tek rotasyon
RR — Sağ-Sağ
z (-2) \ y \ x
→ Sola tek rotasyon
LR — Sol-Sağ
z (+2) / y \ x
→ Sola + Sağa çift rotasyon
RL — Sağ-Sol
z (-2) \ y / x
→ Sağa + Sola çift rotasyon
Durum nasıl belirlenir? BF ≥ +2 ise sol-ağır: sol çocuğun BF'si ≥ 0 ise LL, < 0 ise LR.
BF ≤ -2 ise sağ-ağır: sağ çocuğun BF'si ≤ 0 ise RR, > 0 ise RL.

AVL Düğüm Yapısı

AVL düğümü BST düğümüne ek olarak height alanı taşır. BF ayrı saklanmaz — gerektiğinde sol ve sağ yüksekliklerden hesaplanır.

avl.c — yapı ve yardımcı fonksiyonlar
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int           data;
    struct Node*  left;
    struct Node*  right;
    int           height;   // ← AVL ek alanı
} Node;

/* ── Yardımcı fonksiyonlar ── */
int height(Node* n) {
    return n ? n->height : -1;
}

int maxOf(int a, int b) {
    return a > b ? a : b;
}

int getBF(Node* n) {
    return n ? height(n->left) - height(n->right) : 0;
}

void updateHeight(Node* n) {
    n->height = 1 + maxOf(height(n->left), height(n->right));
}

Node* yeniDugum(int data) {
    Node* n = (Node*)malloc(sizeof(Node));
    if (!n) { perror("malloc"); exit(1); }
    n->data   = data;
    n->left   = NULL;
    n->right  = NULL;
    n->height = 0;  // yaprak: h=0
    return n;
}

Sağa Rotasyon (Right Rotation)

Sağa rotasyon, LL dengesizliğini (sol-sol: BF ≥ +2 ve sol çocuğun BF ≥ 0) düzeltir. Dengesiz düğüm (z) aşağıya, sol çocuğu (y) yukarıya çıkar.

Sağa Rotasyon — 3 Pointer Değişikliği:
1. y = z'nin sol çocuğu (yeni kök olacak)
2. z'nin sol çocuğu = y'nin sağ alt ağacı (T2)
3. y'nin sağ çocuğu = z (z aşağı iner)
4. Yükseklikleri güncelle: önce z, sonra y

Genel Şema — Sağa Rotasyon

Right Rotation: z'yi sağa döndür → y yeni kök
Önce (LL dengesizlik)
zBF=+2yT3T1T2taşınacak
Sonra (dengeli)
yyeni kökzT1T2z'nin solu olduT3
T2, y'nin sağından z'nin soluna taşındı — BST sıralaması korundu: T1 < y < T2 < z < T3

Somut Örnek — LL: insert(10) → insert(20) → insert(30) sil, tersten: 30, 20, 10

LL Dengesizlik: 30 → 20 → 10 eklendiğinde
Dengesiz (BF=+2 at 30)
30+220+110
Sağa rotasyon
⟳ →
30'da döndür
Dengeli ✓
2001030
Pointer değişimleri: ① y=20 (30'un solu) ② 30'un solu = 20'nin sağı (NULL) ③ 20'nin sağı = 30

Sağa Rotasyon Kodu

sagaRotasyon() — O(1)
/*      z             y
 *     / \           / \
 *    y   T3  →    T1   z
 *   / \               / \
 *  T1  T2           T2   T3
 */
Node* sagaRotasyon(Node* z) {
    Node* y  = z->left;       // ① y = sol çocuk
    Node* T2 = y->right;      // T2'yi kaydet

    y->right = z;             // ② y'nin sağı = z (z aşağı)
    z->left  = T2;            // ③ z'nin solu = T2

    updateHeight(z);           // önce z (artık alt düğüm)
    updateHeight(y);           // sonra y (yeni kök)

    return y;                  // yeni kök
}

Sola Rotasyon (Left Rotation)

Sola rotasyon, RR dengesizliğini (sağ-sağ: BF ≤ -2 ve sağ çocuğun BF ≤ 0) düzeltir. Sağa rotasyonun tam ayna görüntüsüdür.

Genel Şema — Sola Rotasyon

Left Rotation: z'yi sola döndür → y yeni kök
Önce (RR dengesizlik)
zBF=-2T1yT2taşınacakT3
Sonra (dengeli)
yyeni kökzT1T2z'nin sağı olduT3
T2, y'nin solundan z'nin sağına taşındı — BST: T1 < z < T2 < y < T3 ✓

Somut Örnek — RR: 10, 20, 30 ekleniyor

RR Dengesizlik: 10 → 20 → 30 eklendiğinde
Dengesiz (BF=-2 at 10)
10-220-130
Sola rotasyon
⟲ →
10'da döndür
Dengeli ✓
2001030

Sola Rotasyon Kodu

solaRotasyon() — O(1)
/*    z                 y
 *   / \              / \
 *  T1  y    →      z   T3
 *     / \         / \
 *    T2  T3     T1   T2
 */
Node* solaRotasyon(Node* z) {
    Node* y  = z->right;      // ① y = sağ çocuk
    Node* T2 = y->left;       // T2'yi kaydet

    y->left  = z;             // ② y'nin solu = z (z aşağı)
    z->right = T2;            // ③ z'nin sağı = T2

    updateHeight(z);
    updateHeight(y);

    return y;                  // yeni kök
}
Simetri: Sola ve sağa rotasyon birbirinin ayna görüntüsüdür. sagaRotasyon'da left↔right değiştirirsen solaRotasyon'u elde edersin. Her ikisi de O(1) — sadece 3 pointer değişikliği + 2 yükseklik güncellemesi.

Sol-Sağ Rotasyon (LR — Çift Rotasyon)

LR dengesizliği, düğüm sol-ağır (BF ≥ +2) ama yeni eleman sol çocuğun sağ tarafına eklendiğinde oluşur — "zikzak" deseni. Tek rotasyon bu deseni çözmez. Çözüm: önce sol çocuğu sola döndür (LR → LL'ye dönüştür), sonra dengesiz düğümü sağa döndür.

LR Rotasyonu — 2 Aşama:
1. Sol çocuğa (y) sola rotasyon uygula → zikzak düzelir, LL kalıbı oluşur.
2. Dengesiz düğüme (z) sağa rotasyon uygula → denge sağlanır.

Kısaca: solaRotasyon(z->left) sonra sagaRotasyon(z)

Neden Tek Rotasyon Yetmez?

LR dengesizlik (zikzak)
30+210-120
Sadece sağa rotasyon
⟳ →
Hâlâ dengesiz! (ters zikzak)
10-23020
Tek sağa rotasyon zikzakı sadece ters çeviriyor → dengesizlik devam ediyor!

LR Çözümü — 3 Aşamada: 30, 10, 20

LR Çift Rotasyon — Aşama Aşama
① Orijinal (LR)
30+210-120
BF(30)=+2, BF(10)=-1
→ LR durumu
Sola döndür
(10'da)
⟲→
② LL'ye dönüştü
30+220+110
Zikzak düzeldi!
Artık düz LL kalıbı
Sağa döndür
(30'da)
⟳→
③ Dengeli ✓
20BF=01030
20 kök oldu
10<20<30 ✓

Sağ-Sol Rotasyon (RL — Çift Rotasyon)

RL dengesizliği LR'nin ayna görüntüsüdür: düğüm sağ-ağır (BF ≤ -2) ama yeni eleman sağ çocuğun sol tarafına eklenmiş. Çözüm: önce sağ çocuğu sağa döndür (RL → RR'ye dönüştür), sonra dengesiz düğümü sola döndür.

RL Rotasyonu — 2 Aşama:
1. Sağ çocuğa (y) sağa rotasyon uygula → zikzak düzelir, RR kalıbı oluşur.
2. Dengesiz düğüme (z) sola rotasyon uygula → denge sağlanır.

Kısaca: sagaRotasyon(z->right) sonra solaRotasyon(z)

RL Çözümü — 3 Aşamada: 10, 30, 20

RL Çift Rotasyon — Aşama Aşama
① Orijinal (RL)
10-230+120
BF(10)=-2, BF(30)=+1
→ RL durumu
Sağa döndür
(30'da)
⟳→
② RR'ye dönüştü
10-220-130
Zikzak düzeldi!
Artık düz RR kalıbı
Sola döndür
(10'da)
⟲→
③ Dengeli ✓
20BF=01030
20 kök oldu
10<20<30 ✓

4 Rotasyon — Karar Tablosu

DurumBF(z)BF(çocuk)KalıpRotasyon
LL≥ +2sol çocuk BF ≥ 0z-y-x düz solSağa tek rotasyon (z'de)
RR≤ -2sağ çocuk BF ≤ 0z-y-x düz sağSola tek rotasyon (z'de)
LR≥ +2sol çocuk BF < 0z-y-x zikzak ↙↘Sola(y'de) + Sağa(z'de)
RL≤ -2sağ çocuk BF > 0z-y-x zikzak ↘↙Sağa(y'de) + Sola(z'de)
Hatırlatma formülü:
• Düz desen (LL/RR) → tek rotasyon (karşı yönde)
• Zikzak desen (LR/RL) → çift rotasyon (önce düzelt, sonra tek rotasyona indirge)

Çift rotasyonda ilk rotasyon çocuğa, ikinci rotasyon dengesiz düğüme uygulanır.

Dengeli Ekleme (AVL Insert)

AVL ekleme = BST ekleme + yükseklik güncelleme + dengeleme. Her eklemenin ardından, ekleme yolundaki düğümlerin yükseklikleri ve BF'leri kontrol edilir. |BF| ≥ 2 bulunursa uygun rotasyon uygulanır.

Dengeleme Fonksiyonu

balance() — 4 durumu kontrol et
Node* balance(Node* node) {
    int bf = getBF(node);

    // Sol-ağır (BF ≥ +2)
    if (bf > 1) {
        if (getBF(node->left) < 0) {
            // LR: önce sol çocuğu sola döndür
            node->left = solaRotasyon(node->left);
        }
        // LL (veya LR→LL dönüşmüş): sağa döndür
        return sagaRotasyon(node);
    }

    // Sağ-ağır (BF ≤ -2)
    if (bf < -1) {
        if (getBF(node->right) > 0) {
            // RL: önce sağ çocuğu sağa döndür
            node->right = sagaRotasyon(node->right);
        }
        // RR (veya RL→RR dönüşmüş): sola döndür
        return solaRotasyon(node);
    }

    return node;  // dengeli, rotasyon gerekmez
}

AVL Ekleme Kodu

avlEkle() — BST ekleme + denge
Node* avlEkle(Node* node, int deger) {
    // ── Adım 1: Standart BST ekleme ──
    if (!node)
        return yeniDugum(deger);

    if (deger < node->data)
        node->left  = avlEkle(node->left, deger);
    else if (deger > node->data)
        node->right = avlEkle(node->right, deger);
    else
        return node;  // duplicate, ekleme

    // ── Adım 2: Yükseklik güncelle ──
    updateHeight(node);

    // ── Adım 3: Dengele (gerekirse rotasyon) ──
    return balance(node);
}
Zarafet: AVL ekleme, BST eklemeden sadece 2 satır daha uzun: updateHeight ve balance. Özyineleme dönüşünde her düğüm otomatik kontrol edilir — dengesizlik her zaman ekleme yolundaki ilk BF ≥ 2 olan düğümde yakalanır.

Adım Adım — AVL Ağacı Büyümesi

Ekleme sırası: 40, 20, 60, 10, 30, 25 — son ekleme LR rotasyonu tetikler.

6 Ekleme — Rotasyon Anı
+40, +20, +60
402060
Dengeli, rotasyon yok
+10, +30
40BF=+120BF=0601030
Hâlâ dengeli (tüm BF ∈ {-1,0,+1})
+25 → LR Rotasyon!
25<40→sol, 25>20→sağ, 25<30→sol → 30'un soluna eklendi
40BF=+2 ✗20BF=-160103025YENİ
BF(40)=+2, BF(20)=-1 → LR durumu
LR Rotasyon Sonucu: solaRot(20) + sagaRot(40)
30BF=020BF=040BF=+1102560
30 yeni kök oldu. Inorder: 10 20 25 30 40 60 — sıralı ✓ Tüm BF ∈ {-1,0,+1} ✓

Dengeli Silme (AVL Delete)

AVL silme = BST silme + yükseklik güncelleme + dengeleme. Aynı balance() fonksiyonu kullanılır — ekleme ve silme arasında fark yoktur. Tek farklılık: ekleme en fazla 1 rotasyon gerektirir, silme ise köke kadar birden fazla rotasyon gerektirebilir (her seviyede bir).

avlSil() — BST silme + denge
Node* bstMin(Node* n) {
    while (n->left) n = n->left;
    return n;
}

Node* avlSil(Node* node, int deger) {
    if (!node) return NULL;

    // ── Adım 1: Standart BST silme ──
    if (deger < node->data) {
        node->left = avlSil(node->left, deger);
    } else if (deger > node->data) {
        node->right = avlSil(node->right, deger);
    } else {
        // Düğüm bulundu — 3 BST silme durumu
        if (!node->left) {
            Node* temp = node->right;
            free(node);
            return temp;  // yaprak veya tek sağ çocuk
        }
        if (!node->right) {
            Node* temp = node->left;
            free(node);
            return temp;  // tek sol çocuk
        }
        // İki çocuk: inorder successor ile değiştir
        Node* succ = bstMin(node->right);
        node->data = succ->data;
        node->right = avlSil(node->right, succ->data);
    }

    // ── Adım 2: Yükseklik güncelle ──
    updateHeight(node);

    // ── Adım 3: Dengele ──
    return balance(node);
}

Silme Örneği — delete(60)

LR rotasyonu sonrası ağaçtan 60'ı sil
Önce (delete 60)
302040102560SİL
60 silindi → 40'ta BF=+1 → 30'da BF=+2!
30'da LL: sağa rotasyon → 20 yeni kök
20BF=010302540
Inorder: 10 20 25 30 40 — sıralı ✓ | Tüm BF dengeli ✓
Ekleme vs Silme: Eklemede en fazla 1 rotasyon yeterlidir (ilk dengesiz atada). Silmede ise köke kadar her seviyede rotasyon gerekebilir — ama pratikte bu nadir ve toplam maliyet yine O(log n)'dir.

Tam Demo Program

main() — sıralı veri bile dengeli kalır
void inorder(Node* n) {
    if (!n) return;
    inorder(n->left);
    printf("%d ", n->data);
    inorder(n->right);
}

void agacBilgi(Node* root) {
    printf("  Inorder:   "); inorder(root); printf("\n");
    printf("  Kök: %d | Yükseklik: %d | Kök BF: %d\n",
           root->data, root->height, getBF(root));
}

int main() {
    Node* root = NULL;

    printf("=== AVL Ağacı Demo ===\n\n");

    // Sıralı veri ekle — BST'de dejenere olurdu!
    printf("--- Sıralı Ekleme: 10,20,30,40,50,60,70 ---\n");
    int degerler[] = {10,20,30,40,50,60,70};
    for (int i = 0; i < 7; i++) {
        root = avlEkle(root, degerler[i]);
        printf("insert(%d) → kök=%d, h=%d\n",
               degerler[i], root->data, root->height);
    }
    agacBilgi(root);

    // Arama
    printf("\n--- Arama ---\n");
    printf("search(50): %s\n",
           bstAra(root,50) ? "Bulundu ✓" : "Yok");
    printf("search(35): %s\n",
           bstAra(root,35) ? "Bulundu" : "Bulunamadı ✗");

    // Silme
    printf("\n--- Silme ---\n");
    root = avlSil(root, 20);
    printf("delete(20): "); agacBilgi(root);

    root = avlSil(root, 40);
    printf("delete(40): "); agacBilgi(root);

    root = avlSil(root, 10);
    printf("delete(10): "); agacBilgi(root);

    printf("\nBST'de sıralı ekleme → h=6 (O(n))\n");
    printf("AVL'de sıralı ekleme → h=%d (O(log n)) ✓\n",
           root->height);

    return 0;
}
çıktı
=== AVL Ağacı Demo ===

--- Sıralı Ekleme: 10,20,30,40,50,60,70 ---
insert(10) → kök=10, h=0
insert(20) → kök=10, h=1
insert(30) → kök=20, h=1        ← RR rotasyon: 10→20 kök oldu
insert(40) → kök=20, h=2
insert(50) → kök=20, h=2        ← RR rotasyon: 40'ta
insert(60) → kök=40, h=2        ← RR rotasyon: 20→40 kök oldu
insert(70) → kök=40, h=2        ← RR rotasyon: 60'ta
  Inorder:   10 20 30 40 50 60 70
  Kök: 40 | Yükseklik: 2 | Kök BF: 0

--- Arama ---
search(50): Bulundu ✓
search(35): Bulunamadı ✗

--- Silme ---
delete(20):   Inorder:   10 30 40 50 60 70
  Kök: 40 | Yükseklik: 2 | Kök BF: 0
delete(40):   Inorder:   10 30 50 60 70
  Kök: 50 | Yükseklik: 2 | Kök BF: 0
delete(10):   Inorder:   30 50 60 70
  Kök: 50 | Yükseklik: 2 | Kök BF: -1

BST'de sıralı ekleme → h=6 (O(n))
AVL'de sıralı ekleme → h=2 (O(log n)) ✓

Karmaşıklık Analizi

OperasyonBST (en kötü)AVL (her zaman)Ek maliyet
EklemeO(n)O(log n)+ en fazla 1 rotasyon
AramaO(n)O(log n)yok (BST aramayla aynı)
SilmeO(n)O(log n)+ en fazla O(log n) rotasyon
Min / MaxO(n)O(log n)yok
RotasyonO(1)sadece pointer değişikliği
Alan (düğüm başı)3 alan4 alan+height alanı
AVL yükseklik sınırı: n düğümlü bir AVL ağacının yüksekliği en fazla 1.44 × log₂(n+2)'dir. Bu, mükemmel dengeli ağaçtan (log₂ n) sadece %44 daha yüksek demektir. Pratikte genellikle çok daha yakın. Örneğin 1.000.000 düğüm: mükemmel denge h ≈ 20, AVL en kötü h ≈ 29.

AVL vs BST vs Diğer Yapılar

YapıAramaEklemeSilmeSıralı çıktı
Sıralı diziO(log n)O(n)O(n)O(n)
Bağlı listeO(n)O(1)O(n)O(n log n)
BST (ortalama)O(log n)O(log n)O(log n)O(n)
BST (en kötü)O(n)O(n)O(n)O(n)
AVL (garanti)O(log n)O(log n)O(log n)O(n)

AVL Ağacının Güçlü ve Zayıf Yönleri

Güçlü Yönler

Kesin O(log n) garanti — veri dağılımından bağımsız.

Daha sıkı denge — Red-Black'e göre daha kısa yükseklik, arama daha hızlı.

Basit mantık — 4 durum, 2 temel rotasyon.

Sıralı erişim — inorder O(n) ile sıralı çıktı.

Zayıf Yönler

Ekleme/silme ek maliyeti — her operasyonda yükseklik güncelleme + BF kontrolü.

Silmede çoklu rotasyon — köke kadar rotasyon gerekebilir.

Ekstra bellek — her düğümde height alanı (4 byte).

Yazma yoğun iş yüklerinde Red-Black daha az rotasyon yapar.
AVL vs Red-Black Tree: AVL daha sıkı denge tutar (daha kısa yükseklik → arama daha hızlı). Red-Black daha gevşek denge tutar (daha az rotasyon → ekleme/silme daha hızlı). Okuma ağırlıklı iş yükünde AVL, yazma ağırlıklı iş yükünde Red-Black tercih edilir. Pratikte fark çoğu zaman ihmal edilebilir düzeydedir.

Sonuç

AVL ağacı, BST'nin dengesizlik sorununu zarif bir mekanizmayla çözer: her düğümde |BF| ≤ 1 kuralını 4 rotasyon türü ile korur. Sıralı veri eklense bile yükseklik O(log n) kalır — 1.000.000 elemanda en fazla ~29 karşılaştırma.

Rotasyonların mantığı basittir: düz desen (LL/RR) tek rotasyonla, zikzak desen (LR/RL) çift rotasyonla düzelir. Ekleme ve silme kodu BST'den sadece updateHeight + balance satırları kadar farklıdır — aynı balance() fonksiyonu her iki operasyonda da kullanılır.

Bölüm 6.4.1 özeti: AVL = BST + otomatik dengeleme. BF = h(sol) - h(sağ), |BF| ≤ 1 olmalı. 4 durum: LL→sağa, RR→sola, LR→sola+sağa, RL→sağa+sola rotasyon. Rotasyon O(1). Ekleme: BST ekleme + güncelle + dengele → en fazla 1 rotasyon. Silme: BST silme + güncelle + dengele → en fazla O(log n) rotasyon. Tüm operasyonlar garanti O(log n). AVL yükseklik ≤ 1.44 × log₂(n+2).
← Veri Yapıları