Menu
CoddyTech

AVL Tree

Terakhir diperbarui

AVL tree adalah binary search tree yang menyeimbangkan dirinya sendiri (self-balancing). Cara kerjanya seperti BST biasa, tetapi setelah setiap penyisipan, AVL tree memeriksa balance factor setiap leluhur, yaitu selisih tinggi antara subtree kiri dan kanannya. Jika ada node yang menjadi tidak seimbang (selisihnya lebih dari 1), pohon melakukan rotasi untuk memulihkan keseimbangan. Tekan Putar di atas untuk melihat nilai disisipkan dan pohon berotasi kembali ke bentuknya.

Karena pohon tidak pernah dibiarkan lebih dari sedikit miring, AVL tree menjamin tinggi O(log n), sehingga pencarian, penyisipan, dan penghapusan selalu O(log n), bahkan untuk input terurut yang akan merusak BST biasa. Harganya adalah rotasi tambahan dan pencatatan tinggi pada setiap penyisipan.

Kompleksitas waktu dan ruang

OperasiKompleksitasCatatan
PencarianO(log n)Tinggi selalu ~1,44 log n
PenyisipanO(log n)Ditambah O(1) rotasi
PenghapusanO(log n)Ditambah O(log n) rotasi
RuangO(n)Satu field tinggi per node

Empat kasus rotasi

KasusKetidakseimbanganPerbaikan
Left-LeftBerat di kiri dari anak kiriSatu rotasi kanan
Right-RightBerat di kanan dari anak kananSatu rotasi kiri
Left-RightBerat di kanan dari anak kiriRotasi kiri, lalu rotasi kanan
Right-LeftBerat di kiri dari anak kananRotasi kanan, lalu rotasi kiri

Contoh penerapan

Menyisipkan [10, 20, 30, 40, 50, 25] satu nilai demi satu nilai:

LangkahStrukturAksi
Sisipkan 1010Node pertama menjadi root; seimbang
Sisipkan 2010(_, 20)Masuk ke kanan 10; masih seimbang
Sisipkan 3020(10, 30)Right-Right di 10, jadi satu rotasi kiri mengangkat 20 menjadi root
Sisipkan 4020(10, 30(_, 40))Masuk ke kanan 30; setiap balance factor tetap dalam ±1
Sisipkan 5020(10, 40(30, 50))Right-Right di 30, jadi rotasi kiri di 30 mengangkat 40
Sisipkan 2530(20(10, 25), 40(_, 50))Right-Left di 20: rotasi kanan pada subtree 40, lalu rotasi kiri pada 20

Kapan memakai AVL tree

Pakai saatHindari saat
Pencarian jauh lebih sering daripada penyisipan dan kamu ingin tinggi pohon serendah mungkinPenyisipan dan penghapusan mendominasi: rotasi dan penyeimbangan ulang tambahannya lebih mahal daripada red-black tree
Kamu butuh kasus terburuk O(log n) yang terjamin, bahkan untuk input yang sengaja buruk atau sudah terurutHash table biasa sudah cukup: kamu tidak butuh penelusuran berurutan atau range query
Kamu butuh operasi berurutan: penelusuran in-order, predecessor/successor, range queryDatanya sangat kecil: BST biasa atau array terurut lebih sederhana dan sudah cukup cepat
Data mungkin datang dalam keadaan terurut, yang akan mengubah BST tak seimbang menjadi linked listKamu tidak sanggup menanggung memori tambahan untuk field tinggi di setiap node karena ruang yang sangat terbatas

Kode AVL Tree

Implementasi AVL Tree yang rapi dan siap dijalankan dalam Python, JavaScript, Java, C++, C. Pilih bahasa, salin kodenya, atau buka langsung di Coddy Playground.

Kode AVL Tree dalam Python

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)
Jalankan kode ini di Playground Python

FAQ AVL Tree

Apa itu balance factor pada AVL tree?

Balance factor sebuah node adalah tinggi subtree kirinya dikurangi tinggi subtree kanannya. AVL tree menjaga balance factor setiap node di -1, 0, atau +1; jika sebuah penyisipan membuatnya keluar dari rentang itu, rotasi akan memulihkan keseimbangan.

Apa perbedaan AVL tree dan red-black tree?
Keduanya adalah BST yang menyeimbangkan diri dengan operasi O(log n). AVL tree diseimbangkan lebih ketat, jadi pencarian sedikit lebih cepat, tetapi bisa melakukan lebih banyak rotasi saat penyisipan/penghapusan. Red-black tree diseimbangkan lebih longgar dan mengutamakan rotasi yang lebih sedikit. Itulah sebabnya banyak library standar memakainya untuk map dan set.
Mengapa memakai AVL tree, bukan binary search tree biasa?
BST biasa bisa merosot menjadi operasi O(n) jika nilai datang dalam urutan terurut sehingga membentuk rantai yang miring. AVL tree berotasi agar tetap seimbang, sehingga menjamin tinggi dan operasi O(log n) apa pun urutan penyisipannya.
Apakah AVL tree lebih baik daripada red-black tree untuk indeks database?

Tergantung beban kerjanya. AVL tree diseimbangkan lebih kaku, jadi unggul saat pembacaan mendominasi dan kamu ingin jalur pencarian sependek mungkin. Namun, sebagian besar database dan library bahasa memilih red-black tree (atau B-tree) karena keduanya menyeimbangkan ulang dengan rotasi yang lebih sedikit pada beban kerja yang banyak menulis, dan hal itu lebih penting saat penyisipan dan penghapusan sering terjadi.

Berapa banyak rotasi yang dibutuhkan satu penyisipan AVL?
Paling banyak satu rotasi, entah rotasi tunggal atau rotasi ganda (dua langkah), untuk menyeimbangkan ulang pohon setelah menyisipkan satu nilai. Itu karena penyisipan menambah tinggi sebuah subtree paling banyak satu, jadi satu perbaikan di leluhur tak seimbang yang paling bawah sudah cukup. Penghapusan berbeda: bisa membutuhkan hingga O(log n) rotasi karena penyeimbangan ulang merambat ke arah root.
Apakah tinggi node perlu diperbarui setelah setiap rotasi?

Ya. Bug yang umum adalah memutar pointer dengan benar tetapi lupa menghitung ulang tinggi dua node yang terlibat. Setelah setiap rotasi, kamu harus memperbarui tinggi node yang diturunkan terlebih dahulu, lalu node yang dinaikkan, karena tinggi node yang dinaikkan bergantung pada anak-anak barunya. Jika langkah ini dilewati, balance factor menjadi usang dan merusak keputusan penyeimbangan berikutnya.

Ilustrasi bahasa pemrograman di Coddy

Kuasai algoritma bersama Coddy

Mulai