Binary Search Tree
Binary Search Tree
1. Pre-order
a. Cetak data pada root
b. Secara rekursif mencetak seluruh data pada subpohon kiri
c. Secara rekursif mencetak seluruh data pada subpohon kanan
2. In-order
a. Secara rekursif mencetak seluruh data pada subpohon kiri
b. Cetak data pada root
c. Secara rekursif mencetak seluruh data pada subpohon kanan
3. Post-order
a. Secara rekursif mencetak seluruh data pada subpohon kiri
b. Secara rekursif mencetak seluruh data pada subpohon kanan
c. Cetak data pada root
Keterangan :
1. Bandingkan 9 dengan 15; mengujungi kiri
2. Bandingkan 9 dengan 6; mengunjungi kanan
3. Bandingkan 9 dengan 7; mengunjungi kanan
4. Bandingkan 9 dengan 13; mengunjungi kiri
5. Bandingkan 9 dengan 9; data ditemukan
Contoh : Mencari nilai 9
Insert BST
Delete BST
Operasi delete memiliki 3 kemungkinan :
- Delete terhadap node tanpa anak/child (leaf/daun) : node dapat langsung dihapus
- Delete terhadap node dengan satu anak/child : maka node anak akan menggantikan posisinya.
- Delete terhadap node dengan dua anak/child : maka node akan digantikan oleh node paling kiri dari
Sub Tree Kanan atau dapat juga digantikan oleh anak paling kanan dari Sub Tree Kiri.
Delete BST
Syntax Program
//header file
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
while(curr != NULL)
{
if(curr->data == del)
{
flag = true;
//cout<<"Data ditemukan!";
break;
}
else
{
parent = curr;
if(del>curr->data)
curr = curr->kanan;
else
curr = curr->kiri;
}
}
if(!flag)
{
cout<<"Data tidak ditemukan. Penghapusan tidak dilakukan."<<endl;
return;
}
return;
}
}
//lebih dari satu tingkat, sehingga node curr mempunyai parent
else if(height(pohon) > 0)
{
//1. jika node yang dihapus tidak memiliki anak
if( curr->kiri== NULL && curr->kanan == NULL)
{
//jika node merupakan anak kiri dari parent
if(parent->kiri == curr)
{
//replace parent->kiri dengan NULL
parent->kiri = NULL;
delete curr;
}
else //jika node merupakan anak kanan dari parent
{
//replace parent->kanan dengan NULL
parent->kanan = NULL;
delete curr;
}
return;
}
}
return;
}
}
}
//fungsi utama
int main()
{
//deklarasikan variabel
char pil;
int del,cari;
while (true)
{
system("cls"); //bersihkan layar
char data;
printf("\t#PROGRAM TREE C++#");
printf("\n\t==================");
printf("\nMENU");
printf("\n----\n");
printf("[1] Tambah Data\n");
printf("[2] Lihat Pre-Order\n");
printf("[3] Lihat In-Order\n");
printf("[4] Lihat Post-Order\n");
printf("[5] Delete\n");
printf("[6] Kosongkan Data\n");
printf("[7] Search\n");
printf("[8] Hitung Node pada Tree\n");
printf("[9] Kedalaman Tree\n");
printf("[X] Keluar\n");
printf("Pilihan Anda : ");
scanf("%c",&pil);
fflush(stdin); //mengosongkan buffering
switch(pil)
{
//jika pil bernilai '1'
case '1':
printf("\nINPUT : ");
printf("\n-------");
printf("\nMasukkan data: ");
scanf("%d", &data);
//panggil fungsi untuk menambah node yang berisi data pada
tree
tambah(&pohon,data);
_getch();
break;
_getch();
break;
_getch();
break;
_getch();
break;
_getch();
break;
_getch();
break;
_getch();
break;
_getch();
break;
_getch();
break;
Penjelasan :
Pada Program ini dideklarasikan beberapa fungsi untuk melakukan operasi pada Tree, fungsi
tersebut antara lain :
o void search(Node **root, int cari)
o void postOrder(Node *root)
o void inOrder(Node *root)
o void preOrder(Node *root)
o void tambah (Node **root, int databaru)
o int height(Node *root)
o int count(Node *root)
o void hapus(Node **root, int del)
Pada posting ini hanya akan dijelaskan beberapa fungsi yang belum pernah dibahas pada posting
sebelumnya. Fungsi tersebut adalah
Hitung jumlah node dalam tree
int count(Node *root)
{
if(root==NULL)
return 0;
else
return count(root->kiri)+ count(root->kanan)+1;
}
Jika root bernilai NULL, Artinya tree masih kosong, maka akan memberikan nilai balik berupa 0.
Sebaliknya, jika root tidak bernilai NULL maka penghitungan jumlah node dalam tree dilakukan
dengan cara mengunjungi setiap node, dimulai dari root ke subtree kiri, kemudian ke subtree kanan
dan masing-masing node dicatat jumlahnya, dan terakhir jumlah node yang ada di subtree kiri
dijumlahkan dengan jumlah node yang ada di subtree kanan ditambah 1 yaitu node root.
Penghapusan Node
Operasi delete memiliki 3 kemungkinan :
- Delete terhadap node tanpa anak/child (leaf/daun) : node dapat langsung dihapus
- Delete terhadap node dengan satu anak/child : maka node anak akan menggantikan posisinya.
- Delete terhadap node dengan dua anak/child : maka node akan digantikan oleh node paling kiri dari
Sub Tree Kanan atau dapat juga digantikan oleh anak paling kanan dari Sub Tree Kiri.
Output
1. Tambah data (Data yang diinput berturut-turut adalah 56, 20, 8, 15, 34, 32, 45, 72, 60, 90, 74,
94 ). Output yang ditampilkan adalah output dari input data terakhir.
#PROGRAM TREE C++#
==================
MENU
----
[1] Tambah Data
[2] Lihat Pre-Order
[3] Lihat In-Order
[4] Lihat Post-Order
[5] Delete
[6] Kosongkan Data
[7] Search
[8] Hitung Node pada Tree
[9] Kedalaman Tree
[X] Keluar
Pilihan Anda : 1
INPUT :
-------
Masukkan data: 94
Data Bertambah!
2. Lihat pre-order
3. Lihat in-order
#PROGRAM TREE C++#
==================
MENU
----
[1] Tambah Data
[2] Lihat Pre-Order
[3] Lihat In-Order
[4] Lihat Post-Order
[5] Delete
[6] Kosongkan Data
[7] Search
[8] Hitung Node pada Tree
[9] Kedalaman Tree
[X] Keluar
Pilihan Anda : 3
OUTPUT IN ORDER :
-----------------
8 15 20 32 34 45 56 60 72 74 90 94
4. Lihat post-order
#PROGRAM TREE C++#
==================
MENU
----
[1] Tambah Data
[2] Lihat Pre-Order
[3] Lihat In-Order
[4] Lihat Post-Order
[5] Delete
[6] Kosongkan Data
[7] Search
[8] Hitung Node pada Tree
[9] Kedalaman Tree
[X] Keluar
Pilihan Anda : 4
6. Kedalaman(ketinggian) Tree
#PROGRAM TREE C++#
==================
MENU
----
[1] Tambah Data
[2] Lihat Pre-Order
[3] Lihat In-Order
[4] Lihat Post-Order
[5] Delete
[6] Kosongkan Data
[7] Search
[8] Hitung Node pada Tree
[9] Kedalaman Tree
[X] Keluar
Pilihan Anda : 9
7. Search Node
#PROGRAM TREE C++#
==================
MENU
----
[1] Tambah Data
[2] Lihat Pre-Order
[3] Lihat In-Order
[4] Lihat Post-Order
[5] Delete
[6] Kosongkan Data
[7] Search
[8] Hitung Node pada Tree
[9] Kedalaman Tree
[X] Keluar
Pilihan Anda : 7
OUTPUT -> Hanya untuk mengecek apakah data dimaksud terdapat dalam tree
------
PRE ORDER : 56 20 8 15 34 32 45 72 60 90 74 94
IN ORDER : 8 15 20 32 34 45 56 60 72 74 90 94
POST ORDER : 15 8 32 45 34 20 60 74 94 90 72 56
PENCARIAN DATA
--------------
Masukkan data yang ingin dicari : 74
Data ditemukan!
8. Delete Node
#PROGRAM TREE C++#
==================
MENU
----
[1] Tambah Data
[2] Lihat Pre-Order
[3] Lihat In-Order
[4] Lihat Post-Order
[5] Delete
[6] Kosongkan Data
[7] Search
[8] Hitung Node pada Tree
[9] Kedalaman Tree
[X] Keluar
Pilihan Anda : 5
PENGHAPUSAN DATA :
------------------
Masukkan data yang ingin dihapus: 72
9. Kosongkan Data
#PROGRAM TREE C++#
==================
MENU
----
[1] Tambah Data
[2] Lihat Pre-Order
[3] Lihat In-Order
[4] Lihat Post-Order
[5] Delete
[6] Kosongkan Data
[7] Search
[8] Hitung Node pada Tree
[9] Kedalaman Tree
[X] Keluar
Pilihan Anda : 6
PENGOSONGAN ELEMEN
------------------
Tree sudah dikosongkan!!
Ilustrasi Tree
Degree (derajat) adalah jumlah edge yang keluar dan masuk dari sebuah node.
Contoh : node E memiliki in degree 1 dan out degree 2
Root (akar) adalah node yang memiliki derajat keluar >=0 dan derajat masuk = 0.
Contoh : node A adalah root
Subtree / child adalah bagian salah satu node dibawah root sampai ke bawah.
Contoh : tree C adalah right subtree dari A dan tree B merupakan left subtree dari A
node G dan F merupakan child dari node C
node F merupakan parent dari node J dan K
Ancestor adalah Node yang berada di atas node lain.
Contoh : node B adalah ancestor dari node E
Descendant adalah node yang berada di bawah node lain.
Contoh : node E adalah descendant dari node A.
Leaf (daun) adalah semua node yang derajat masuknya 1 dan derajat keluarnya 0.
Contoh : node D, H, I, J, K, dan G adalah leaf
Sibling adalah node yang mempunyai level yang sama dan parent yang sama.
Contoh : node D adalah sibling dari node A
Height (ketinggian) adalah level tertinggi dari tree ditambah 1.
Contoh : height dari tree A adalah 3 + 1 = 4
Weight (bobot) adalah jumlah leaf(daun) pada tree.
Contoh : weight dari tree A adalah 6
BINARY TREE
Sebuah tree dengan syarat bahwa tiap node hanya boleh memiliki maksimal 2 subtree yang disebut
sebagai subpohon kiri(left subtree) dan subpohon kanan (right subtree) dan kedua subtree tersebut harus
terpisah, atau dengan kata lain tiap node dalam binary tree hanya boleh memiliki paling banyak 2 child.
Binary tree terdiri dari :
1. Full Binary Tree : semua node (kecuali leaf pasti memiliki 2 anak dan tiap subtree memiliki panjang
path yang sama)
import java.util.*;
class Node{
int data;
Node left;
Node right;
Node(int x){
this.data = x;
}
}
/**
* Mengecek apakah tree masih kosong
**/
private boolean isEmpty(){
return (root == null);
}
/**
* Memasukkan suatu nilai ke dalam tree.
* Jika nilai tersebut lebih kecil dari nilai node, maka bergerak
ke kiri terus
* hingga menjadi child, begitu juga sebaliknya.
**/
public void insert(int input){
Node temp = new Node(input);
if (isEmpty())
root = temp;
else {
Node cursor = root,
parent = null;
while (cursor != null){
parent = cursor;
if (input < cursor.data)
cursor = cursor.left;
else
cursor = cursor.right;
}
/**
* Menambahkan Node baru pada kiri/kanan Node parent
bergantung
* pada nilai input dan nilai yang disimpan Node
parent
**/
if (input < parent.data){
parent.left = temp;
return;
}
else {
parent.right = temp;
return;
}
}
}
/**
* Mencari suatu nilai dalam tree berdasarkan prinsip :
* Selama belum menemukan nilai yang sama,
* Jika nilai yang dicari lebih kecil dari nilai yang disimpan
dalam Node
* maka bergerak ke left Child begitu juga sebaliknya.
**/
public Node find(int key){
Node cursor = root;
while (cursor != null){
if (cursor.data == key)
return cursor;
else if (key < cursor.data)
cursor = cursor.left;
else
cursor = cursor.right;
}
return null;
}
public boolean delete(int key){
Node cursor = root,
parent = null;
boolean found = false,
isLeftChild = true; //menandai apakah Node
yang dihapus merupakan left child
if (!isEmpty()){
while (cursor != null){
parent = cursor;
if (key == cursor.data){
found = true;
break;
}
else if (key < cursor.data){
isLeftChild = true;
cursor = cursor.left;
}
else {
isLeftChild = false;
cursor = cursor.right;
}
}
if (!found)
return false;
else {
/**
* Untuk menghapus leaf (tidak punya child)
**/
if (cursor.left == null && cursor.right ==
null){
if (cursor == root)
root = null;
else if (isLeftChild)
parent.left = null;
else
parent.right = null;
}
/**
* Jika node yang akan dihapus hanya memiliki
salah satu subtree
* maka tinggal memindahkan subtree
menggantikan node yang dihapus
**/
else if (cursor.left == null){
if (cursor == root)
root = cursor.right;
else if (isLeftChild)
parent.left = cursor.right;
else
parent.right = cursor.right;
}
else if (cursor.right == null){
if (cursor == root)
root = cursor.left;
else if (isLeftChild)
parent.left = cursor.left;
else
parent.right = cursor.left;
}
/**
* Jika node yang akan dihapus memiliki 2
child, maka cari successornya
* dengan fungsi getSuccessor kemudian
hubungkan subtree bagian kanan
* dari node yang dihapus dengan successor
**/
else {
Node successor =
getSuccessor(cursor);
if (cursor == root)
root = successor;
else if (isLeftChild)
parent.left = successor;
else
parent.right = successor;
//menyambung successor dengan
cursor.right
successor.right = cursor.right;
}
}
}
return true;
}
/**
* Mencari nilai terbesar yang mendekati nilai yang disimpan Node
* yang dihapus, Ilustrasi :
*
* 65
* 59 72
* 32 64
* 62
* misal : nilai yang dihapus 65, maka nilai terbesar yang
mendekati adalah 64.
* maka ambil 64 sebagai successor, kemudian gabungkan
* 59
* 32 63
* Kemudian satukan keduanya :
* 64
* 59
* 32 63
* Jadilah urutan tree yang masih memenuhi syarat Binary Search
Tree
**/
private Node getSuccessor(Node localNode){
Node parent = null,
successor = localNode,
cursor = localNode.left;
while (cursor != null){
parent = successor;
successor = cursor;
cursor = cursor.right;
}
if (successor != localNode.left){
parent.right = successor.left;
successor.left = localNode.left;
}
return successor;
}
/**
* Method traverse untuk mengelilingi Node-Node dalam tree
**/
public void traverse(int tipe){
switch (tipe){
case 1:
System.out.print("\nPreorder traversal:\n");
preOrder(root);
break;
case 2:
System.out.print("\nInorder traversal:\n");
inOrder(root);
break;
case 3:
System.out.print("\nPostorder traversal:\n");
postOrder(root);
break;
}
System.out.println('\n');
}
private void preOrder(Node localRoot){
if (localRoot == null) return;
System.out.print(localRoot.data+" ");
preOrder(localRoot.left);
preOrder(localRoot.right);
}
private void inOrder(Node localRoot){
if (localRoot == null) return;
inOrder(localRoot.left);
System.out.print(localRoot.data+" ");
inOrder(localRoot.right);
}
private void postOrder(Node localRoot){
if (localRoot == null) return;
postOrder(localRoot.left);
postOrder(localRoot.right);
System.out.print(localRoot.data+" ");
}