”Trees, Binary Trees dan Binary Search Trees” Syarif Abdullah (G551150381)∗†
Matematika Terapan Departemen Matematika FMIPA IPB e-mail: syarif
[email protected] &
[email protected] 17 Januari 2016 Deskripsi: Merangkum catatan kuliah Metode Komputasi pada tanggal 23 Desember 2015 yaitu tentang Binary Search Trees. Selain itu penulis juga menambahkan beberapa materi untuk melengkapi catatan dengan mengambil dan mempelajari dari beberapa artikel dan buku. Pembahasan: ⇒Trees, Binary Trees dan Binary Search Trees ⇒Pre-Order In-Order dan Post-Order pada Trees ⇒Binary Search Tree ⇒Insert Binary Search Trees dan Algoritmanya ⇒Delete Binary Search Trees dan Algoritmanya ⇒Balance Tree Single Rotation dan Double Rotations ⇒Aplikasi Tree dengan Program Scilab - Trees, Binary Trees dan Binary Search Trees Definisi Tree Tree merupakan salah satu bentuk struktur data tidak linear yang menggambarkan hubungan yang bersifat hierarkis (hubungan one to many) antara elemen-elemen. Tree bias didefinisikan sebagai kumpulan simpul/node dengan elemen khusus yang disebut Root. Node lainnya terbagi menjadi himpunan-himpunan yang saling tak berhubungan satu sama lain (disebut Subtree). Untuk lebih jelasnya, di bawah akan diuraikan istilahistilah umum dalam tree. Predecessor : Node yang berada di atas node tertentu Successor : Node yang berada dibawah node tertentu Ancestor : Seluruh node yang terletak sebelum node tertentu dan terletak pada jalur yang sama Descendant : Seluruh node yang terletak sesudah node tertentu dan terletak pada jalur yang sama Parent : Predecessor satu level di atas suatu node Child : Successor satu level di bawah suatu node Sibling : Node-node yang memiliki parent yang sama dengan suatu node Subtree : Bagian dari tree yang berupa suatu node beserta descendantnya dan memiliki semua karakteristik dari tree tersebut. Size : Banyaknya node dalam suatu tree Height : Banyaknya tingkatan / level dalam suatu tree Root : Satu-satunya node khusus dalam tree yang tak punyak predecessor Leaf : Node-node dalam tree yang tak memiliki successor Degree : Banyaknya child yang dimiliki suatu node ∗ http † File
://syarif abdullah.student.ipb.ac.id/ dibuat dengan LYX Program
1
Binary Tree Binary Tree adalah tree dengan syarat bahwa tiap node hanya boleh memiliki maksimal dua subtree dan kedua subtree tersebut harus terpisah. Sesuai dengan definisi tersebut tiap node dalam binary tree hanya boleh memiliki paling banyak dua child. Berikut adalah contoh dari Tree:
Gambar 1 : Tree
Ancestor (f) : c, a Descendant (c) : f, g Parent (d) : b Child (a) : b, c Sibling (f) : g Size : 7 Height : 3 Root : a Leaf : d, e, f, g Degree (c) : 2
Struktur Data Dasar Tree
Gambar 2: Struktur Data Dasar Tree Struktur Data Aktual Tree
Gambar 3: Struktur Data Aktual Tree Jenis- Jenis Binary Tree : Full Binary Tree : Jenis binary tree ini tiap nodenya (kecuali leaf) memiliki dua child dan tiap subtree harus mempunyai panjang path yang sama. Complete Binary Tree : Jenis ini mirip dengan Full Binary Tree, namun tiap subtree boleh memiliki panjang path yang berbeda dan setiap node kecuali leaf hanya boleh memiliki 2 child. 2
Skewed Binary Tree : Skewed Binary Tree adalah Binary Tree yang semua nodenya (kecuali leaf) hanya memiliki satu child. Operasi-operasi pada Binary Tree Create : Membentuk binary tree baru yang masih kosong Clear : Mengosongkan binary tree yang sudah ada Empty : Function untuk memeriksa apakah binary tree masih kosong Insert : Memasukkan sebuah node ke dalam tree. Ada tiga pilihan insert : sebagai root, left child, atau right child. Khusus insert sebagai root, tree harus dalam keadaan kosong Find : Mencari root, parent, left child, atau right child dari suatu node. (tree tidak boleh kosong). Update : Mengubah isi dari node yang ditunjuk oleh pointer curret (Tree tidak boleh kosong) Retrieve : Mengetahui isi dari node yang ditunjuk oleh pointer current (Tree tidak boleh kosong) DeleteSub : Menghapus sebuah subtree (node beserta seluruh descendantnya) yang ditunjuk current. Tree tidak boleh kosong. Setelah itu, pointer current dakan berpindah ke parent dari node yang dihapus. Characteristic : Mengetahui karakteristik dari suatu tree, yakni: size, height, serta average length. Tree tidak boleh kosong. Traverse : Mengunjungi seluruh node-node pada tree, masing-masing sekali. Hasilnya adalah urutan informasi secara linear yang tersimpan dalam tree. Ada tiga cara traverse,yaitu PreOrder, InOrder, dan PostOrder. - Pre-Order In-Order dan Post-Order pada Trees Langkah-langkah Tranverse : PreOrder : cetak isi node yang dikunjungi, kunjungi Left Child, kunjungi Right Child. InOrder : kunjungi Left Child, cetak isi node yang dikunjungi, kunjungi Right Child. PostOrder : kunjungi Left Child, kunjungi Right Child cetak isi node yang dikunjungi. Algoritma Menentukan Transversal pada Pre-Order dalam bahasa Pascal adalah sebagai berikut: PROCEDURE preorder(t: Node); BEGIN IF t # NIL THEN P(t); preorder(t.left); preorder(t.right) END END preorder Algoritma Menentukan Transversal pada In-Order dalam bahasa Pascal adalah sebagai berikut: PROCEDURE inorder(t: Node); BEGIN IF t # NIL THEN inorder(t.left); P(t);
3
inorder(t.right) END END inorder Algoritma Menentukan Transversal pada Post-Order dalam bahasa Pascal adalah sebagai berikut: PROCEDURE postorder(t: Node); BEGIN IF t # NIL THEN postorder(t.left); postorder(t.right); P(t) END END postorder Algoritma Menentukan Transversal pada Pre-Order dalam bahasa C adalah sebagai berikut: preorder(node * n){ node * c; if (! n==NULL){ DO SOMETHING; c = n->first child; while (! c==NULL){ preorder(c); c = c->next sibling; } } Sedangkan Algoritma Menentukan Transversal pada Post-Order adalah sebagai berikut: postorder(node * n){ node * c; if (! n==NULL){ c = n->first child; while (! c==NULL){ postorder(c); c = c->next sibling; } DO SOMETHING; } Contoh Transversal:
4
Gambar 4: Transversal Pada Contoh di atas didapatkan Pre-Order Transversalnya adalah : * + a / b c - d * e f Pada Contoh di atas didapatkan Pre-Order Transversalnya adalah : a + b / c * d - e * f Pada Contoh di atas didapatkan Pre-Order Transversalnya adalah : a b c / + d e f * - * Algoritma Menentukan Depth (kedalaman) pada Tree dalam bahasa C adalah sebagai berikut: Depth(node * n, int d){ node * c; if (! n==NULL){ n->depth = d; d = d+1; c = n->first child; while (! c==NULL){ Depth(c, d); c = c->next sibling; } } Algoritma Menentukan Size (ukuran) pada Tree dalam bahasa C adalah sebagai berikut: Size(node * n){ node * c; if (! n==NULL) return 0; else { int m=1; c = n->first child; while (! c==NULL){ m = m + Size(c); c = c->next sibling; } return m; } Algoritma Mencetak/Print Tree dalam bahasa C adalah sebagai berikut: print(node * root){ node * n, c; queue Q; Q.enqueue(root); while (! Q.empty()){ n = Q.dequeue(); print n->data; c = n->first child; while (! c==NULL){ Q.enqueue(c); c = c->next sibling; } } } - Binary Search Tree Binary Tree ini memiliki sifat dimana semua left child harus lebih kecil dari pada right child dan parentnya. Semua right child juga harus lebih besar dari left child serta parentnya. Binary search tree dibuat untuk mengatasi kelemahan pada binary tree biasa, yaitu kesulitan dalam searching / pendarian node tertentu dalam binary tree. Pada dasarnya operasi dalam Binary Search Tree sama dengan Binary Tree biasa, kecuali pada operasi insert, update, dan delete. Berikut adalah contoh dari Binary Search Tree dan bukan. 5
Gambar 5a : Binary Search Tree
Gambar 5b : Bukan Binary Search Tree
Pada Gambar 5a di atas merupakan Binary Search Tree karena setiap none memiliki maksimal 2 node, sedangkan pada Gambar 5b di atas bukan merupakan Binary Search Tree karena pada node 5 mempunyai banyak cabang/tangan lebih dari 2. Contoh In-Order Listing pada Binary Search Tree:
Gambar 6 : In-Order Binary Search Tree Dari Gambar 6 didapatkan In-Order Binary Search Tree adalah: 2 → 5 → 7 → 9 → 10 → 15 → 17 → 20 → 30 Berikuta adalah Algoritma pencarian node dengan bahasa C Node *& find(Comparable x, Node * root) { if (root == NULL) return root; else if (x < root->key) return find(x, root->left); else if (x > root->key) return find(x, root->right); else return root; } - Insert Binary Search Trees dan Algoritmanya Memasukkan sebuah node ke dalam tree. Ada tiga pilihan insert : sebagai root, left child, atau right child. Khusus insert sebagai root, tree harus dalam keadaan kosong.
6
Berikut adalah Algoritma insert node dengan bahasa C void insert(Comparable x, Node * root) { assert ( root != NULL ); if (x < root->key){ if (root->left == NULL) root->left = new Node(x); else insert( x, root->left ); } else if (x > root->key){ if (root->right == NULL) root->right = new Node(x); else insert( x, root->right ); } } Contoh : akan dimasukkan node-node sebagai berikut, 1; 2; 3; 4; 5; 6; 7; 8; 9 dengan urutan 5; 3; 7; 2; 4; 6; 8; 1; 9
Gambar 7a : Insert Binary Search Tree Awal
Gambar 7b : Insert Binary Search Tree Akhir
- Delete Binary Search Trees dan Algoritmanya Menghapus sebuah subtree (node beserta seluruh descendantnya) yang ditunjuk current. Tree tidak boleh kosong. Setelah itu, pointer current dakan berpindah ke parent dari node yang dihapus. Namun kita juga dapat menghapus hanya satu node saja pada sebuah trees. Sebelum kita meghapus suatu node, kita harus mengetahui dan dapat menentukan Predecessor dan Succesor. Predecessor adalah node yang berada di atas node tertentu, dan Succesor adalah node yang berada dibawah node tertentu. Berikut adalah algoritma-algoritmanya: Berikut adalah Algoritma Menemukan Succesor node dengan bahasa C Node * succ(Node * root) { if (root->right == NULL) return NULL; else return min(root->right); } Berikut adalah Algoritma Menemukan Predecessor node dengan bahasa C Node * pred(Node * root) { if (root->left == NULL) return NULL; else
7
return max(root->left); } Berikut adalah Algoritma delete node dengan bahasa C void delete(Comparable x, Node *& p) { Node * q; if (p != NULL) { if (p->key < x) delete(x, p->right); else if (p->key > x) delete(x, p->left); else { /* p->key == x */ if (p->left == NULL) p = p->right; else if (p->right == NULL) p = p->left; else { q = successor(p); p->key = q->key; delete(q->key, p->right); } } }} Berikut adalah contoh delete node pada suatu tree yang paling sederhana.
Gambar 8a : Delete Node 17
Gambar 8b : Hasil Delete Node 17
Pada Contoh di atas jika kita menghapus node 17 maka penghapusan ini tergolong sangat sederhana karena kita tinggal menghapus node tanpa mencari succecor atau Predesessornya. Berikut adalah contoh delete node pada suatu tree yang paling tidak sederhana.
8
Gambar 9a : Delete Node 15
Gambar 9b : Hasil Delete Node 15
Pada Contoh di atas jika kita menghapus node 15 maka penghapusan ini tergolong tidak sederhana. Sehingga kita gantikan Node 15 dengan menaikkan Node 20. Selanjutnya kita akan menghapus node 5:
Gambar 10b : Delete Node 5
Gambar 10b : Hasil Delete Node 5
Pada Contoh di atas jika kita menghapus node 5 maka penghapusan ini tergolong tidak sederhana. Sehingga kita gantikan Node 5 dengan menaikkan Node 7. Sebenarnya pada langkah penghapusan node 15 dan node 5 di atas kita telah melakukan pencarian Succesor dan Predecessor sebagai berikut:
9
Gambar 11a : Pencarian Succesor
Gambar 11b : Pencarian Predesessor
Gambar 11c : Hasil Delete Node 15 dan 5 - Balance Tree Single Rotation dan Double Rotations Suatu Tree dikatakan balance(seimbang) jika perbedaan/selisih high sebelah kanan dan kiri antara -1 dan 1.
Gambar 12 : Balance Tree Ada beberapa kasus insert node dan delete node untuk menjadikan tree tersebut tetap balance. Sehingga dibutuhkan suatu rotasi untuk mendapatkan tree tersebut tetap balance apabila dilakukan insert maupun delete node. Kasus 1 dengan menggunakan Single Rotation Bila didapatkan insert atau delete node sehingga didapatkan bentuk node seperti berikut:
10
Gambar 13 : Single Rotation Kasus 2 dengan menggunakan Double Rotation Bila didapatkan insert atau delete node sehingga didapatkan bentuk node seperti berikut:
Gambar 14 : Double Rotations Contoh: Misalkan kita akan melakukan insert node 18 pada tree berikut:
Gambar 15 : Insert Balance Binary Tree Dengan menggunakan Single Rotation maka didapatkan,
Gambar 16 : Insert Single Rotation Dengan menggunakan Double Rotation maka didapatkan,
11
Gambar 17a : Insert Double Rotation 1
Gambar 17b : Insert Double Rotation 1 - Aplikasi Tree dengan Program Scilab Berikut adalah beberapa perinah untuk membuat suatu Tree pada Program Scilab yang telah dibuat oleh penulis dan menampilkannya. root = uiCreateNode(’Ayis’, ’iconAyis’, ’callbackAyis’); node1 = uiCreateNode(’Bono’, ’iconNode1’, ’callbackNode1’); leaf11 = uiCreateNode(’Dono’, ’iconLeaf1.1’, ’callbackLeaf1.1’); leaf12 = uiCreateNode(’Eni’, ’iconLeaf1.2’, ’callbackLeaf1.2’); node2 = uiCreateNode(’Cinta’, ’iconNode2’, ’callbackNode2’); leaf21 = uiCreateNode(’Fitay’, ’iconLeaf2.1’, ’callbackLeaf2.1’); leaf22 = uiCreateNode(’Gino’, ’iconLeaf2.2’, ’callbackLeaf2.2’); treeNode1 = uiCreateTree(node1, leaf11, leaf12); treeNode2 = uiCreateTree(node2, leaf21, leaf22); treeAyis = uiCreateTree(root, treeNode1, treeNode2); uiDisplayTree(treeAyis) // Membuat node baru myNode = uiCreateNode(’Cinta’, ’iconNode2’, ’callbackNode2’) // Menemukan node jika treeAyis memuat myNode result = uiFindNode(treeAyis, myNode) //akan menghasilkan ’result = list(node1)’ // Menemukan node pada posisi ’1.1’ result = uiFindNode(treeAyis, ’3.1’)
12
//akan menghasilkan ’result = list(leaf31)’ //Menemukan node dimana ’text’ sama dengan ’Cinta’ result = uiFindNode(treeAyis, ’label’, ’Cinta’) //akan menghasilkan ’result = list(node2)’
Gambar 18 : Tree/Binary Tree pada Program Scilab Sekian Pembahasan kali ini. Kurang lebihnya mohon maaf. Semoga Bermanfaat. Amin. Profile: Nama : Syarif Abdullah Tmpt/Tgl Lahir : Gresik, 26 Januari 1986 Alamat : Leran Manyar Gresik Jawa Timur NRP : G551150381 Jurusan : Matematika Terapan Departement : Matematika Fakultas : Matematika dan Ilmu Pengetahuan Alam Universitas : Institut Pertanian Bogor Hobby : Baca buku dan utek-utek soal E-mail : syarif
[email protected] Web/Blog : http ://syarif abdullah.student.ipb.ac.id/
13