Handout No: 18 [Handout
berikutnya, sebelumnya, atau kembali ke
halaman
utama]
Struktur Data Hirarkis: 2-3 Tree dan B-Tree
7 April 1999
Goal: 2-3 tree, red-black tree, (a,b) tree, B-tree, B*-Tree
Disclaimer: pada tanggal 7 April 1999 page ini baru selesai 60% ....
jadi jangan buru-buru diprint
Pengantar
AVL tree dalam pembahasan sebelumnya adalah salah satu suatu bentuk aplikasi
tree sebagai tabel indeks. Alternatif struktur hirarkis lain untuk indexing
adalah keluarga (a,b)-tree tree yang bukan binary tree. 2-3 Tree adalah
versi yang paling sederhana dan B-Tree adalah versi yang paling populer
digunakan dalam sistem basis data. Kelebihan struktur ini adalah dalam
kestabilan performance pencarian logaritmisnya. Sebagaimana yang kita ketahui,
AVL tree masih memungkinkan adanya perbedaan performance worse-case dan
best-case.
Definisi: suatu 2-3 tree adalah tree yang
-
dapat memiliki cabang berjumlah 0, 2, atau 3.
-
Node-node leaf selalu berada pada level yang sama.
Dalam fungsinya sebagai suatu tabel indeks maka setiap node dapat berisi
2 key yaitu apabila memiliki 3 cabang atau merupakan leaf. Suatu node berisi
2 key disebut node-3 dan node dengan 1 key disebut node-2. Note: bilangan
2 dan 3 menunjukkan jumlah cabang yang ia miliki jika internal node, sebagai
leaf maka penamaan tersebut tetap berlaku sesuai dengan jumlah key seolah
leaf memiliki 2 atau 3 cabang kosong.
Keterurutan key pada Node-2 dengan key=K1:
-
key-key di cabang kiri < K1 < key-key di cabang kanan
Keterurutan pada Noe-3 dengan key K1 dan K2 (K1 < K2):
-
key-key di cabang kiri < K1 < key-key di cabang tengah
-
key-key di cabang tengah < K1 < key-key di cabang kanan
Dengan definisi demkian maka apabila setiap node dalam 2-3 tree
merupakan node-2 maka akan terbentuk perfect binary tree, sementara itu
apabila setiap node dalam 2-3 tree merupakan node-3 maka akan terbentuk
perfect ternary tree. Pada kedua bentuk perfect tree tersebut kedalaman
rata-rata dari tiap node adalah hampir sama dengan tinggi dari tree.
Pertanyaan: untuk jumlah node N berapa tinggi minimal dan maksimal
dari 2-3 tree yang dapat terbentuk?
Penyisipan Suatu Key K
Dalam memahami proses penyisipan suatu key dalam 2-3 tree kita bayangkan
node-node tree tersebut sebagai ruang-ruang yang elastis dengan kapasitas
max 2 key dan apabila dimuati lebih dari kapasitas maka
mula-mula key tersebut masuk tapi kemudian balon tsb. pecah.
-
Mula-mula cari suatu leaf yang sesuai untuk menempatkan K tersebut.
Masukanlah key tersebut pada node leaf tersebut. Kita sebut secara umum
node ini sebagai P. Selanjutnya terdapat kasus-kasus pada P.
-
P sebelumnya sebelumnya node-2 (berisi satu key) maka operasi selesai karena
masih di dalam kapasitas node serta pula P kemudian menjadi node-3.
-
P sebelumnya node-3, sekarang P kelebihan muatan dengan tiga
key: K1, K2, dan K3 (K1 < K2 < K3), maka "pecah" node P (sebenarnya
yang terjadi adalah, create satu node lainnya) menjadi
dua node: P1 dan P2; jika P adalah internal node maka pemecahan
menyertakan cabang-cabang disebelahnya
-
P1 node di sebelah kiri ditempati oleh K1,
-
P2 node di sebelah kanan ditempati oleh K3,
-
sementara untuk K2 dilakukan:
-
jika P bukan root maka K2 disisipkan ke node ayah dari P, dan
pada ayah P di tambahkan satu pointer baru untuk menghubungkan ayah
P dengan P1 dan P2.
-
Jika P adalah root maka create node baru untuk
menempatkan K2 yang kemudian menjadi root baru dan menghubungkan
pointer kiri ke P1 dan pointer kanan ke P2.
-
Ulangi prosedur pemeriksaan ini untuk ayah P sebagai P.
Penghapusan suatu Key K
-
Cari node yang berisikan key tersebut. Jika node ini bukan leaf maka
cari node leaf yang berisikan key yang merupakan inorder predesesor dari
K misalnya L dan memindahkan L tersebut ke tempat K semula sehingga
masalahnya menjadi menghapus key dalam leaf.
Untuk selanjutnya node leaf ini kita sebut P secara umum.
P semula bisa merupakan node-2 atau node-3 sehingga
sekarang menjadi bersisa satu key atau kosong.
-
Jika P masih bersisa satu key maka proses selesai
-
Jika tidak (P menjadi kosong) periksa lagi:
jika P adalah root maka hapus node P, dan selesai (tentu saja jika
P memiliki cabang maka node cabangnya menjadi root sekarang.
- jika tidak (bukan root) maka terdapat kasus-kasus
yang masing-masing memerlukan operasi transformasi yang berbeda:
-
Kasus 1: P memiliki sibling tepat di kirinya yang memiliki 2 key.
Sibling tersebut adalah Q dan kedua key adalah K1 dan K2 (dimana
K1 < K2), maka apabila key yang memperantarainya di node ayah P adalah
K3 maka dilakukan rotasi:
K3 menempati P, K2 menggantikan K3, dan K1 tinggal sendirian di Q. Perpindahan
ini disertai oleh perpindahan subtree-subtree yang berkaitan dengan key
ybs.
-
Kasus 2: P tidak memenuhi kasus 1,
tapi memiliki sibling tepat di kanannya yang memiliki 2 key
sibling tersebut adalah R dan kedua key adalah K1 dan K2 (di mana
K1 < K2). Apabila ada dan key K3 di ayah P memperantarai P dan R maka
dilakukan rotasi:
K3 menempati P, K1 menggantikan K3, dan K2 tinggal sendirian di R.
-
Kasus 3: P tidak memenuhi kasus 1 dan 2, tapi
memiliki sibling tepat dikirinya yang hanya memiliki 1 key.
Misalkan sibling tersebut adalah Q tersebut dan S adalah node
ayah dari P dan Q.
Pindahkan key yang memperantarai P dan Q dalam S ke Q sehingga kemudian
Q berisi dua key, serta P dapat di hapus berikut pointer pada S.
-
Kasus 4: P tidak memenuhi hasus 1, 2, dan 3, tapi
memiliki sibling tepat dikanannya yang hanya memiliki 1 key.
Misalkan sibling tersebut adalah Q tersebut dan S adalah node
ayah dari P dan Q.
Pindahkan key yang memperantarai P dan Q dalam S ke Q sehingga kemudian
Q berisi dua key, serta P dapat di hapus berikut pointer pada S.
M/li>
-
Khusus pada kasus 3 atua 4, node S sekarang bisa menjadi kosong atau
masih bersisa 1 key, maka jika S menjadi kosong lanjutkan proses dengan
S sekarang sebagai P.
Implementasi
Dengan bahasa pemrograman biasa maka implementasi node-2 dan node -3 memerlukan
penanganan dengan algoritma yang berbeda. Beberapa bahasa pemrograman,
menyediakan variant records (Pascal atau C), yaitu memungkinkan node-2
dan node-3 didekarasikan dalam satu block record dengan suatu variant flag.
Namun dalam penanganannya tetap harus dibedakan. Selain itu, untuk kedua
jenis node kompiler akan mengalokasikan space yang sama dengan mengambil
space terbesarnya. Dalam bahasa pemrograman berorientasi obyek seperti
C++ dan Java kedua node didefinisikan sebagai dua kelas yang berbeda dan
merupakan subclass dari satu generic node class. Dalam hal ini algoritma
manipulasinya bisa lebih disederhanakan karena sudah terdeferensiasi di
dalam metoda-metodanya sendiri. Namun tentu saja sebagaimana umumnya konsep
pemrograman berorientasi obyek, terdapat overhead cost yang lain untuk
itu.
Dalam Java spesifikasi dari node 2-3 tree.
class TwoThreeTreeNode{
public void insertKey(KeyType x) {
}
}
class NodeTwo extends TwoThreeNode{
public void insertKey(KeyType x) {
}
}
class NodeThree extends TwoThreeNode {
public void insertKey(KeyType x) {
}
}
Sebagai suatu ADT maka 2-3 Tree dapat diimplementasikan dengan suatu
struktur Binary Search Tree yang memiliki sifat khusus yaitu Red-Black
Tree.
Red-Black Tree
Red-Black Tree adalah suatu BST yang mana node-node dan edge-edge memiliki
warna merah atau hitam. Warna dari root selalu hitam. Warna dari edge yang
menghubungkan ayah dengan anaknya selalu berwarna sama dengan warna node
anak tersebut.
Dalam merepresentasikan 2-3 Tree ke dalam Red-Black Tree maka diaplikasikan
aturan berikut. Jika setiap node-3 yang berisi key a dan b dan ketiga cabangnya
(t1, t2, dan t3) dipecahkan sbb.
atau
Selanjutnya hasil dari konversi 2-3 Tree menjadi Red-Black akan menghasilkan
pewarnaan node dan edge dalam keteraturan sebagai berikut.
-
Pada setiap path dari root ke leaf, jumlah edge hitam adalah sama
-
Node merah yang bukan leaf selalu memiliki dua anak hitam.
-
Suatu node hitam yang bukan merupakan leaf bisa memiliki:
-
dua anak hitam;atau
-
satu anak merah dan satu anak hitam; atau
-
satu anak tunggal yang merah.
(a,b)-Tree
Generalisasi dari 2-3 Tree adalah (a,b)-tree yaitu suatu tree di mana
-
setiap internal nodenya dapat memiliki a atau a+1 atau a+2 atau . . . atau
b cabang serta (a < b)
-
node leaf selalu berada pada level yang sama.
Aplikasinya berbeda dari 2-3 tree: Data hanya disimpan pada node
leaf sedangkan internal node pada (a,b)-tree hanya merupakan pembanding
mengarahkan pada node leaf yang sesuai. Jadi key-key dalam internal node
hanya dummy key (bisa duplikasi dengan real key) dan berfungsi sebagai
pengarah pada pencarian node leaf di mana data berada.
Penyisipan dan penghapusan data mirip dengan operasi penyisipan dan
penghapusan pada 2-3 tree.
-
Penyisipan terus berlangsung selama jumlah cabang lebih kecil atau sama
dengan b. Manakala jumlah cabang mencapai b+1 maka node tersebut dipecah
dua masing-masing membawa a cabang.
-
Penghapusan terus dapat dilakukan pada suatu node selama jumlah cabang
lebih besar atau sama dengan a. Kurang dari a maka dilakukan rotasi dari
sibling node langsung yang berlebih atau jika tidak ada sibling langsung
yang berlebih dilakukan penggabungan.
B-Tree
B-tree adalah (a,b)-tree di mana b = 2a - 1. a dan b biasanya merupakan
angka-angka yang cukup besar, misalnya a = 100 dan b = 199.
Hal tersebut berkaitan dengan fungsi B-tree untuk external data structure.
Setiap node berukuran sesuai dengan ukuran data block. Misalnya terdapat
satu juta item data yang disimpan pada external storage dan terbagi-bagi
atas blok-blok. Sejumlah blok tambahan digunakan untuk menyimpan masing-masing
internal node dan masing-masing interbal node dapat berisi 100 hingga 199
pointer. Retrieval suatu data paling buruk dilakukan dengan pembacaan 3
block internal node dan satu block node leaf yang berisi data yang dicari.
Operasi block pada external storage biasa terjadi untuk mengurangi overhead
cost untuk sistem mekanis alat baca pada pembacaan persatuan unit data.
B*-Tree
B*-tree adalah variant dari B-tree di mana pada node leaf (node berisi
data) disertakan suatu pointer tambahan untuk menghubungkan setiap leaf
node tersebut sebagai suatu linear linked-list. Struktur ini memungkinkan
akses sikuensial data dalam B-tree tanpa harus turun-naik pada struktur
hirarkisnya.