Menu
Coddy logo textTech

AVL Ağacı

Son güncelleme

AVL ağacı, kendini dengeleyen bir ikili arama ağacıdır. Normal bir BST gibi çalışır, ancak her eklemeden sonra her atanın denge faktörünü - sol ve sağ alt ağaçları arasındaki yükseklik farkını - kontrol eder ve herhangi bir düğüm dengesiz hale gelirse (1'den büyük bir fark), dengeyi yeniden sağlamak için dönüşler gerçekleştirir. Değerlerin eklendiğini ve ağacın kendini tekrar şekle sokmak için döndüğünü görmek için yukarıdaki oynat düğmesine basın.

Ağacın hafifçe bile fazla eğilmesine asla izin vermediği için, bir AVL ağacı O(log n) yükseklik garanti eder, böylece arama, ekleme ve silme her zaman O(log n) olur - sıradan bir BST'yi mahvedecek sıralı girdiler için bile. Bunun bedeli, her eklemedeki ekstra dönüşler ve yükseklik kayıtlarıdır.

Zaman ve alan karmaşıklığı

İşlemKarmaşıklıkNotlar
AramaO(log n)Yükseklik her zaman ~1.44 log n
EklemeO(log n)Artı O(1) dönüş
SilmeO(log n)Artı O(log n) dönüş
AlanO(n)Düğüm başına bir yükseklik alanı

Dört dönüş durumu

DurumDengesizlikDüzeltme
Sol-SolSol çocuğun solunda ağırBir sağa dönüş
Sağ-SağSağ çocuğun sağında ağırBir sola dönüş
Sol-SağSol çocuğun sağında ağırSola, sonra sağa dönüş
Sağ-SolSağ çocuğun solunda ağırSağa, sonra sola dönüş

Çözümlü örnek

[10, 20, 30, 40, 50, 25] değerlerini teker teker ekleme:

AdımYapıEylem
10 ekle10İlk düğüm kök olur; dengeli
20 ekle10(_, 20)10'un sağına gider; hâlâ dengeli
30 ekle20(10, 30)10'da Sağ-Sağ, bu yüzden bir sola dönüş 20'yi köke çıkarır
40 ekle20(10, 30(_, 40))30'un sağına gider; tüm denge faktörleri ±1 içinde kalır
50 ekle20(10, 40(30, 50))30'da Sağ-Sağ, bu yüzden 30'daki bir sola dönüş 40'ı yükseltir
25 ekle30(20(10, 25), 40(_, 50))20'de Sağ-Sol: 40'ın alt ağacını sağa döndür, sonra 20'yi sola döndür

AVL ağacını ne zaman kullanmalı

Şu durumda kullanınŞu durumda kaçının
Aramalar eklemelerden çok daha fazlaysa ve mümkün olan en sıkı yüksekliği istiyorsanızEklemeler ve silmeler baskınsa - ekstra dönüşler ve yeniden dengeleme, kırmızı-siyah ağaçtan daha pahalıya mal olur
Düşmanca veya sıralı girdiler için bile garantili O(log n) en kötü duruma ihtiyacınız varsaDüz bir hash tablosu yeterliyse - sıralı gezinme veya aralık sorgularına ihtiyacınız yoksa
Sıralı işlemlere ihtiyacınız varsa: sıralı gezinme, öncül/ardıl, aralık sorgularıVeri kümesi çok küçükse - düz bir BST veya sıralı dizi daha basit ve yeterince hızlıdır
Veriler zaten sıralı gelebiliyorsa, bu dengesiz bir BST'yi bağlı listeye dönüştürürÇok dar bir alanda düğüm başına yükseklik alanının ekstra belleğini karşılayamıyorsanız

AVL Tree kodu

Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir AVL Tree uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.

Python ile AVL Tree kodu

Python
1class Node:2    def __init__(self, key):3        self.key = key4        self.left = None5        self.right = None6        self.height = 17
8
9def height(node):10    return node.height if node else 011
12
13def update(node):14    node.height = 1 + max(height(node.left), height(node.right))15
16
17def rotate_right(y):18    x = y.left19    y.left = x.right20    x.right = y21    update(y)22    update(x)23    return x24
25
26def rotate_left(x):27    y = x.right28    x.right = y.left29    y.left = x30    update(x)31    update(y)32    return y33
34
35def insert(node, key):36    if node is None:37        return Node(key)38    if key < node.key:39        node.left = insert(node.left, key)40    else:41        node.right = insert(node.right, key)42    update(node)43    balance = height(node.left) - height(node.right)44    # Four imbalance cases: LL, RR, LR, RL45    if balance > 1 and key < node.left.key:46        return rotate_right(node)47    if balance < -1 and key > node.right.key:48        return rotate_left(node)49    if balance > 1:50        node.left = rotate_left(node.left)51        return rotate_right(node)52    if balance < -1:53        node.right = rotate_right(node.right)54        return rotate_left(node)55    return node56
57
58def inorder(node):59    if node is None:60        return []61    return inorder(node.left) + [node.key] + inorder(node.right)62
63
64root = None65for key in [10, 20, 30, 40, 50, 25]:66    root = insert(root, key)67
68print("Inorder:", inorder(root))69print("Root:", root.key, "| tree height:", root.height)
Bu kodu Python Playground'da çalıştır

AVL Ağacı SSS

AVL ağacında denge faktörü nedir?
Bir düğümün denge faktörü, sol alt ağacının yüksekliği eksi sağ alt ağacının yüksekliğidir. Bir AVL ağacı her düğümün denge faktörünü -1, 0 veya +1'de tutar; bir ekleme onu bu aralığın dışına iterse, bir dönüş dengeyi yeniden sağlar.
AVL ağacı ile kırmızı-siyah ağaç arasındaki fark nedir?
Her ikisi de O(log n) işlemlere sahip kendini dengeleyen BST'lerdir. AVL ağaçları daha katı biçimde dengelidir, bu yüzden aramalar biraz daha hızlıdır, ancak ekleme/silmede daha fazla dönüş yapabilirler. Kırmızı-siyah ağaçlar daha gevşek dengelidir ve daha az dönüşü tercih eder - bu yüzden birçok standart kütüphane bunları haritalar ve kümeler için kullanır.
Neden düz bir ikili arama ağacı yerine AVL ağacı kullanılır?
Düz bir BST, değerler sıralı gelirse eğik bir zincir oluşturarak O(n) işlemlere düşebilir. Bir AVL ağacı dengeli kalmak için döner ve ekleme sırasından bağımsız olarak O(log n) yükseklik ve işlemleri garanti eder.
Bir veritabanı dizini için AVL ağacı kırmızı-siyah ağaçtan daha mı iyidir?
İş yüküne bağlıdır. AVL ağaçları daha katı biçimde dengelidir, bu yüzden okumalar baskın olduğunda ve mümkün olan en kısa arama yollarını istediğinizde kazanırlar. Ancak çoğu veritabanı ve dil kütüphanesi kırmızı-siyah ağaçları (veya B-ağaçlarını) seçer çünkü yazma ağırlıklı iş yüklerinde daha az dönüşle yeniden dengelenirler ki bu, eklemeler ve silmeler sık olduğunda daha önemlidir.
Tek bir AVL eklemesi kaç dönüşe ihtiyaç duyar?
Bir değer ekledikten sonra ağacı yeniden dengelemek için en fazla bir dönüş - ya tek ya da çift (iki adımlı) bir dönüş - gerekir. Bunun nedeni, bir eklemenin bir alt ağacın yüksekliğini en fazla bir artırmasıdır, bu yüzden en alttaki dengesiz atadaki tek bir düzeltme yeterlidir. Silme farklıdır: yeniden dengeleme köke doğru yayılırken O(log n) kadar dönüş gerektirebilir.
Her dönüşten sonra düğüm yüksekliklerini güncellemem gerekir mi?
Evet - yaygın bir hata, işaretçileri doğru döndürmek ama ilgili iki düğümün yüksekliğini yeniden hesaplamayı unutmaktır. Her dönüşten sonra önce indirilen düğümün yüksekliğini, sonra yükseltilen düğümünkini güncellemelisiniz, çünkü yükseltilen düğümün yüksekliği yeni çocuklarına bağlıdır. Bunu atlamak, gelecekteki yeniden dengeleme kararlarını bozan eski denge faktörleri bırakır.
Coddy programming languages illustration

Coddy ile algoritmalarda ustalaş

BAŞLA