praktikum 27-28 binary search tree - Politeknik Elektronika Negeri

advertisement
Politeknik Elektronika Negeri Surabaya
PRAKTIKUM 27-28
BINARY SEARCH TREE
A. TUJUAN
Mahasiswa diharapkan mampu :
1. Memahami dan mengimplementasaikan Konsep Binary Search Tree
2. Memahami keunggulan dari algoritma Binary Search Tree
3. Mampu mengimplementasikan algoritma Binary Search Tree
B. DASAR TEORI
Binary search tree adalah salah satu bentuk dari pohon.Di mana masing-masing pohon
tersebut hanya memiliki dua buah upapohon, yakni upapohon kiri dan upapohon kanan.Ciri khas
yang melekat pada binary search tree ini yang bisa juga dibilang sebagai keunggulan dari binary
search tree adalah peletakan isi dari nodenya yang terurut berdasarkan besarnya dari isinya
tersebut.Isinya bisa saja berupa integer, karakter, atau apapun sesuai dengan spesifikasi binary
search tree yang ada. Operasi dasar dari binary search tree(BST) ini sendiri sangatlah sederhana,
yakni hanya fungsi perbandingan dan fungsi rekursif. Di mana anak pohon sebelah kiri node
adalah anak pohon yang lebih kecil dari node, sedangkan anak pohon sebelah kanan node
memiliki isi yang lebih besar daripada isi node. Biasanya penyimpanan data di dalam binary
search tree ini bisa juga berupa record di mana pengurutannya hanya tinggal melihat key dari
record tersebut, missal nomor absen, NIM, tanggal, dll.
Keunggulan Binary Search
a. Search Method
Metode search adalah penentu paling dalam program atau bisa dibilang nyawa dari
programdatabase. Kenapa search sangat penting untuk efisien.?Bayangkan saja apabila ada
miliaran data yang ada di dalam database pada sebuah komputer server dan harus diolah dan
selalu harus diupdate setiap hari ataupun diakses pengguna untuk dicari isi data yang
diinginkanya. Lalu, yang kita gunakan adalah struktur data yang tidak efisien, di mana suatu
saat computer server akan mengalami minimal hang atau yang paling parah adalah server
down sehingga tidak bisa diakses dan akhirnya justru membuang waktu bahkan lebih
198
Politeknik Elektronika Negeri Surabaya
parahnya bisa menyebabkan data dalam harddisk server menghilang. Tentunya kita sangat
menghindari hal semacam itu terjadi bukan.
Metode Search sendiri ada banyak, seperti yang sudah sempat disinggung sedikit
pada pendahuluan. Bahwa search macamnya ada linear search, binary search, binary search
tree, dll. Di sini hanya akan dibahas 3 contoh tersebut. Linear search merupakan tipe search
yang paling mendasar dalam dunia search. Pada dasarn linear search ini sangat
sederhana.Yakni memulai pencarian dari elemen pertama kemudian bergeser terus ke elemen
berikutnya hingga menemukan isi elemen yang dicari. Apabila elemen yang dicari tidak ada,
maka linear search akan terus melakukan traversal hingga elemen terakhir. Mari kita
bayangkan apabila terdapat banyak sekali data yang harus ditraversal dan data yang dicar
itidak ada di dalam database(worst case possibility). Efektivitas dari linear search ini adalah
dengan O(n) worst case tergantung dari jumlah elemen yang ada di dalam database tersebut.
Metode search yang berikutnya yakni binary search, bedanya binary search dari linear search
adalah dengan pembagian jumlah elemen menjadi dua bagian. Sehingga pencarian bisa lebih
efektif dengan cara membagi pencarian ke dua arah. Worst case dari binary search ini adalah
O(log n) sehingga cara ini bisa dibilang cukup efisien.
Metode search yang terakhir adalah binary search tree (sebenarnya bukan merupakan
metode search). binary search tree memiliki kompleksitas algoritma O(log n) yang tidak ada
bedanya dengan metode binary search. Tetapi seharusnya metode search pada binary search
tree bisa lebih singkat, karena jalur yang dipilih sudah tergolong spesifik, sehingga tidak
perlu memeriksa semua elemen untuk mencari elemen tertentu.
b. Struktur Data
Struktur data merupakan keunggulan dari binary search tree jika kita bandingkan
dengan array pada umunya.Mengapa hal tersebut bisa dibilang sebagai keunggulan? Karne
struktur data dari binary search tree adalah linked list dengan elemennya terurut. Dengan
demikian apabila struktur datanya sudah terurut maka pengaksesannya pun jauh lebih
mudah.Hal yang diakibatkan dari struktur data tersebut adalah kita tidak perlu melakukan
sorting terhadap data yang sudah ada. Berbeda dengan struktur data yang lain,
seperti struktur data array, linked list biasa membutuhkan sebuah fungsi sort untuk
mengurutkan datanya. Keunggulan lain yang disebabkan struktur data dari pohon ini adalah
199
Politeknik Elektronika Negeri Surabaya
kemudahan insertion process. Pada proses pemasukan data padabinary search tree, sangatlah
mudah, sama sekali tidak ada pergeseran data. Proses yang terjadi hanyalah pencarian lokasi
yang tepat untuk data yang dimasukkan tersebut, kemudian dikaitkan ke data di atasnya
sehingga dia menjadi anggota binary search tree yang baru
Gambar 1.Binary Tree
Kendati demikian, struktur data pada binary search tree menyebabkan proses
penghapusan data pada binary search treetergolong cukup rumit. Mengapa rumit? Karena
harus ada traversal data untuk mencari node tertentu untuk menggantikan posisi dari node
yang telah dihapus(informasi akan diperjelas di dalam Gambar). Selain itu, kelemahan
pemasukan data pada binary search tree jika dibandingkan dengan Tabel Eksplisit adalah
table eksplisit tidak memerlukan pengulangan untuk penambahan elemen baru,
sedangkan binary search tree membutuhkan proses sekuensial untuk menambahkan satu
elemen baru. Namun hal tersebut dapat ditutupi dengan sorted element dari binary search
tree.
Gambar 2.Menghapus Node di Binary Tree
200
Politeknik Elektronika Negeri Surabaya
C. TUGAS PENDAHULUAN
Buatlah resume 1 halaman mengenai Binary Search Tree dan berikan penjelasannya.!
D. PERCOBAAN
Node.java
1.
2.
3.
4.
5.
6.
class Node {
int iData; // data yang digunakan sebagai nilai kunci.
Node leftChild; // Simpul rujukan ke anak sebelah kiri.
Node rightChild; // Simpul rujukan ke anak sebelah kanan.
}
BinaryTree.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
class BinaryTree {
private Node root; // Membentuk akar (root) BinaryTree
public Object find(int key) {
Node current = root; // Mulai dari akar (root)
while (current.iData != key) // Selama tidak sesuai
{
if (key < current.iData) // Pergi ke cabang kiri?
{
current = current.leftChild;
} else {
current = current.rightChild; // Atau pergi ke cabang kanan.
}
if (current == null) // Jika tidak memiliki anak.
{
return null;
}
}
return current; // Data yang dicari ditemukan.
}
public void insert(int id) {
{
Node newNode = new Node(); // Membuat Node yang akan
disisipkan.
newNode.iData = id; // Menyisipkan data.
if (root == null) // Jika tidak ada Node di akar (root).
{
root = newNode;
} else {
Node current = root; // Mulai dari akar (root).
Node parent;
while (true) // hadir secara internal.
{
parent = current;
if (id < current.iData) // Pergi ke kiri.
{
201
Politeknik Elektronika Negeri Surabaya
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
current = current.leftChild;
if (current == null) // Akhir cabang kiri.
{ // Sisipkan di kiri.
parent.leftChild = newNode;
return;
}
} // Akhir perjalanan ke kiri.
else // Atau pergi ke kanan.
{
current = current.rightChild;
if (current == null) // Akhir perjalanan cabang kanan.
{ // Sisipkan di kanan.
parent.rightChild = newNode;
return;
}
} // Akhir perjalanan ke kanan.
} // Akhir while
} // Akhir bukan akar (root).
} // Akhir insert()
}
public boolean delete(int id) { // (Asumsi pohon tidak kosong)
Node current = root;
Node parent = root;
boolean isLeftChild = true;
while (current.iData != id) // Mencari Node yang akan dihapus.
{
parent = current;
if (id < current.iData) // Pergi ke kiri?
{
isLeftChild = true;
current = current.leftChild;
} else // Atau pergi ke kanan?
{
isLeftChild = false;
current = current.rightChild;
}
if (current == null) // Akhir baris
{
return false; // Node yang dicari tidak ditemukan.
}
} // end while
// Node yang akan dihapus ditemukan.
// Jika Node tidak memiliki anak, hapus!
if (current.leftChild == null
&& current.rightChild == null) {
if (current == root) // Jika Node yang dihapus merupakan akar (Node).
{
root = null; // Pohon biner menjadi kosong.
} else if (isLeftChild) // Jika Node yang dihapus adalah
anak sebelah kiri.
{
parent.leftChild = null; // Pemutusan koneksi.
} else // Jika Node yang akan dihapus adalah anak sebelah
kanan.
{
202
Politeknik Elektronika Negeri Surabaya
92.
parent.rightChild = null;
93.
}
94.
} // Jika tidak ada anak kanan, ganti dengan subpohon kiri.
95.
else if (current.rightChild == null) {
96.
if (current == root) {
97.
root = current.leftChild;
98.
} else if (isLeftChild) // Anak sebelah kiri induk.
99.
{
100.
parent.leftChild = current.leftChild;
101.
} else // Anak sebelah kanan induk.
102.
{
103.
parent.rightChild = current.leftChild;
104.
}
105.
} // Jika tak ada anak kiri, gantikan dengan subpohon sebelah
kanan.
106.
else if (current.leftChild == null) {
107.
if (current == root) {
108.
root = current.rightChild;
109.
} else if (isLeftChild) // Anak sebelah kiri induk.
110.
{
111.
parent.leftChild = current.rightChild;
112.
} else // Anak sebelah kanan induk.
113.
{
114.
parent.rightChild = current.rightChild;
115.
}
116.
} else // Dua anak, gantikan dengan successor inorder.
117.
{
118. // Mendapatkan successor Node untuk dihapus (current)
119.
Node successor = getSuccessor(current);
120. // Menghubungkan induk Node saat ini ke successor.
121.
if (current == root) {
122.
root = successor;
123.
} else if (isLeftChild) {
124.
parent.leftChild = successor;
125.
} else {
126.
parent.rightChild = successor;
127.
}
128. // connect successor to current's left child
129.
successor.leftChild = current.leftChild;
130.
} // end else two children
131. // (successor tidak mempunyai anak sebwlah kiri)
132.
return true;
133.
} // end delete()
134. // Mengembalikan Node yang memiliki nilai terbesar berikuntnya
setelah delNode,
135. // pergi ke anak kanan, kemudian turunan kiri anak sebalah kanan.
136.
private Node getSuccessor(Node delNode) {
137.
Node successorParent = delNode;
138.
Node successor = delNode;
139.
Node current = delNode.rightChild; // Pergi ke anak sebelah
kanan.
140. while (current != null) // Hingga habis.
141. { // Anak kiri.
142.
successorParent = successor;
143.
successor = current;
144. current = current.leftChild; // Pergi ke anak sebelah kiri.
203
Politeknik Elektronika Negeri Surabaya
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
}
// Jika successor bukan anak seblah kanan.
if (successor != delNode.rightChild) { // Buat hubungan.
successorParent.leftChild = successor.rightChild;
successor.rightChild = delNode.rightChild;
}
return successor;
}
//Mencari simpul (Node) yang memiliki nilai terkecil.
public Node minimum() {
Node current, last = null;
// Mulai dari akar (root).
current = root;
// Hingga dasar pohon biner.
while (current != null) {
// Mencatat Node
last = current;
// Pergi ke anak kiri.
current = current.leftChild;
}
return last;
}
} // end class BinaryTree
TestBinaryTree.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TestBinaryTree {
private static int cari;
private static int cacahData;
public static void main(String[] args) {
BinaryTree bt = new BinaryTree(); // Membuat objek bt bertipe
BinaryTree.
System.out.print("Berapa data yang akan dimasukkan ke BinaryTree? ");
cacahData = inputData();
for (int i = 0; i < cacahData; i++) {
System.out.print("Data ke-" + (i + 1) + " = ");
bt.insert(inputData());
}
System.out.print("Data yang Anda cari ? ");
cari = inputData();
Node found = (Node) bt.find(cari); // find node with key 25
if (found != null) {
System.out.println("Node dengan key " + cari + " ditemukan.");
} else {
System.out.println("Node key " + cari + " tidak dapat ditemukan.");
}
}
private static int inputData() {
BufferedReader bfr = new BufferedReader(new
204
Politeknik Elektronika Negeri Surabaya
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
InputStreamReader(System.in));
String angkaInput = null;
try {
angkaInput = bfr.readLine();
} catch (IOException e) {
e.printStackTrace();
}
int Data = Integer.valueOf(angkaInput).intValue();
return Data;
}
}
E. LATIHAN
Latihan 1 : buat class BinerySearchTree, kemudian analisa dan gambarkan pohonya
sesuai code berikut :
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
import java.util.*;
class Node{
int data;
Node left;
Node right;
Node(int x){
this.data = x;
}
}
public class BinarySearchTree{
private Node root;
/**
* 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;
}
205
Politeknik Elektronika Negeri Surabaya
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
/**
* 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
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
* maka bergerak ke left Child begitu juga sebaliknya.
**/
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;
206
Politeknik Elektronika Negeri Surabaya
91.
92.
93.
}
/* Jika node yang akan dihapus hanya memiliki salah satu
subtree
94.
* maka tinggal memindahkan subtree menggantikan node yang
dihapus
95.
**/
96.
else if (cursor.left == null){
97.
if (cursor == root)
98.
root = cursor.right;
99.
else if (isLeftChild)
100.
parent.left = cursor.right;
101.
else
102.
parent.right = cursor.right;
103.
}
104.
else if (cursor.right == null){
105.
if (cursor == root)
106.
root = cursor.left;
107.
else if (isLeftChild)
108.
parent.left = cursor.left;
109.
else
110.
parent.right = cursor.left;
111.
}
112.
/**
113.
* Jika node yang akan dihapus memiliki 2 child, maka cari
successornya
114.
* dengan fungsi getSuccessor kemudian hubungkan subtree bagian kanan
115.
* dari node yang dihapus dengan successor
116.
**/
117.
else {
118.
Node successor = getSuccessor(cursor);
119.
if (cursor == root)
120.
root = successor;
121.
else if (isLeftChild)
122.
parent.left = successor;
123.
else
124.
parent.right = successor;
125.
//menyambung successor dengan cursor.right
126.
successor.right = cursor.right;
127.
}
128.
}
129.
}
130.
return true;
131.
}
132.
133.
private Node getSuccessor(Node localNode){
134.
Node parent = null,
135.
successor = localNode,
136.
cursor = localNode.left;
137.
while (cursor != null){
138.
parent = successor;
139.
successor = cursor;
140.
cursor = cursor.right;
141.
}
142.
if (successor != localNode.left){
143.
parent.right = successor.left;
207
Politeknik Elektronika Negeri Surabaya
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
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+" ");
}
public static void main(String[] args)
{
BinarySearchTree a = new BinarySearchTree();
//penambahan node pada binary tree
a.insert(5);
a.insert(4);
a.insert(6);
a.insert(1);
a.insert(4);
a.insert(9);
//penelusuran node pada binary tree
a.traverse(1); //pre-order
a.traverse(2); //in-order
208
Politeknik Elektronika Negeri Surabaya
200.
201.
202.
a.traverse(3); //post-order
}
}
Latihan 2 :Dengan menggunakan class BinarySearchTree lakukan pemanggilan method insert()
dengan mengirimkan input berturut-turut sesuai dengan deret berikut : {10, 5,20,2,6,19,25,21},
root adalah 10. Gambarkan hasil akhir binary search tree tersebut!
F. LAPORAN RESMI
Kerjakan hasil percobaan(D) dan latihan(E) di atas dan tambahkan analisa.
209
Download