Hashing and Binary Tree
A. Hashing
Hashing adalah metode yang digunakan untuk mempermudah
penyimpanan dengan cara melakukan ekripsi nilai tertentu dengan kaidah yang
telah ditentukan sebagai “key” dari suatu data.
Hash Table
Adalah table ( dalam bentuk array ) dimana kita menyetor
suatu data, dimana indexnya adalah key dan nilainya (value) adalah data
sebenarnya.
Sebagai contoh, kita akan menyetor beberapa nilai integer
kedalam array yang memiliki index sebanyak 20. Karena index hanya 20, maka key
yang kita buat harus 0 – 20. Nilai key akan ditentukan dengan modulus 20;
Contoh :
Input:
- Value = 20, key =
20 % 20 = 0;
- Value = 5, key =
5%20 = 5;
Hasil
|
index array
|
Key
|
value
|
|
0
|
20
|
20
|
|
1..4
|
|
|
|
5
|
5
|
5
|
|
6…19
|
|
|
Tetapi ada beberapa kondisi yang dapat muncul dalam
melakukan Hashing ini
Contoh :
Input :
- value = 20, key = 0
- value = 1, key = 1;
- value = 21, key = 21 % 20 = 1;
Value 1 dan 21 memiliki key yang sama, kalua dibiarkan maka
value 1 akan di override / ditimpa nilainya oleh 21. Hal ini disebut collision
Untuk menangani collision, ada 2 cara yang dapat diterapkan
yaitu probing dan chaining
1. probing
Berarti jika tempat key sudah diisi, maka data akan diisi
ditempat yang kosong selanjutnya. Hal ini akan memperlambat pencarian jika
sudah banyak tempat yang terisi.
void
insert(int key,int value){
int hash_index = hashCode(key);
// untuk dapatin key yang udah di hash
struct Data *item=
(Data*)malloc(sizeof(Data)); //setor nilai dalam node item
item->key = key;
item->value = value;
while(tabel[hash_index]!=NULL){
//selama tempat itu ga kosong
hash_index++; //
digeser trus sampai t4 kosong
}
hash_index %= size;
tabel[hash_index] = item; //
sampai t4 kosong baru bisa masukin
}
Data*
search(int keyz){
int hash_index = hashCode(keyz);
//mencari nilai key
while(tabel[hash_index]!=NULL){
//masih harus cari karena bisa aja datanya ud tergeser dari
index yang seharusnya
if(tabel[hash_index]->key==keyz){
//klu misalnya ktemu kosong, nanti stop
return
tabel[hash_index];
}
hash_index++; //menambah nilai key sampai ketemu tempat
kosong
hash_index %=
size;
}
// warning : klu semua kotak
terisi dan tidak ada yang dicari, bisa looping forever -> crash
return NULL;
}
void
deletion(int key){
Data *del = search(key); //cari
datanya pkai function search
if(del==NULL){
printf("No
data to be deleted\n");
return;
}
else{
int code =
hashCode(del->key);
while(tabel[code]!=NULL){
if(tabel[code]->key
== key){
printf("(%d,%d) has been
deleted\n",tabel[code]->key,tabel[code]->value);
tabel[code]
= NULL;
}
code++;
code
%= size;
}
// warning : klu
semua kotak terisi dan dkd yang dicari, bisa looping forever -> crash
}
return;
}
Kelemahan
probingakan terlihat dari contoh berikut
Insert(1,20)
, insert(21,21), insert (41,22), insert(2,50)
Maka akan
menghasilkan
|
idx array
|
Key
|
value
|
|
0
|
|
|
|
1
|
1
|
20
|
|
2
|
21
|
21
|
|
3
|
41
|
22
|
|
4
|
2
|
50
|
|
5..19
|
|
|
Bila kita menghapus key 1, maka array index 1 akan memiliki
value null. Lalu Ketika kita ingin menghapus key 21 ataupun 22, maka akan dicek
index 1, yaitu null. Karena null tersebut, maka deletion akan berhenti sehingga
key 21 dan 41 tidak bisa dihapus.
2. Chaining
Bila ada key yang sama, maka akan ditempatkan di next. Cara
kerjanya sama seperti linked list.
void
insert(int key,int value){
int hash_idx = hashCode(key);
Data *item =
(Data*)malloc(sizeof(Data));
item->key = key;
item->value = value;
item->next = NULL;
if(kotak[hash_idx]==NULL){
kotak[hash_idx] =
item;
}
else{
Data *temp =
kotak[hash_idx];
while(temp->next){ //kalau setelah head(index 1) ada
sesuatu, dia looping sampai ga
ada
lagi (ujung)
temp
= temp->next;
}
temp->next =
item; //baru ujungnya ditempelin item
}
}
Data*
search(int key){
int hash_idx = hashCode(key);
while(kotak[hash_idx]!=NULL){
if(kotak[hash_idx]->key==key){
return
kotak[hash_idx];
}
kotak[hash_idx] =
kotak[hash_idx]->next;
}
return NULL;
}
void
deletion(int key){ //deletion v2
int hash_idx = hashCode(key);
if(!kotak[hash_idx]) return;
Data *temp = kotak[hash_idx];
Data *stab;
if(temp->key==key){ // jika
yang mau dihapus data pertama / head
kotak[hash_idx] =
temp->next; //headnya digeser
temp = NULL;
free(temp);
return;
}
while(temp->next!=NULL){
if(temp->next->key==key){
stab
= temp->next;
temp->next
= stab->next;
stab
= NULL;
free(stab);
return;
}
temp =
temp->next;
}
printf("no data to be
deleted\n");
return;
}
Contoh:
Insert(1,20) , insert(21,21), insert (41,22), insert(2,50)
|
Index array
|
key
|
value
|
|
0
|
|
|
|
1
|
1, 21, 41
|
20 -> 21 -> 22
|
|
2
|
2
|
5
|
|
3..19
|
|
|
Jadi cara
terbaik dalam hash table adalah chaining karena lebih efektif, efisien dan aman
dalam insertion, searching, dan deletion.
B. Binary
Search Table
Adalah
struktur data yang setiap nodenya memiliki cabang dua yaitu left dan right, dan
diawali oleh root. Node yang tidak ada cabang disebut leaf.
Metode dalam
bst ada 3 yaitu insert, search, and delete.
struct Node{
int value;
Node *left,*right;
}*curr;
Node
*create(int nilai){
curr =
(Node*)malloc(sizeof(Node));
curr->value = nilai;
curr->left = curr->right =
NULL;
return curr;
}
Node
*insert(Node *root, int nilai){
if(root==NULL) return
create(nilai);
else if(nilai >
root->value){
root->right =
insert(root->right,nilai);
}
else if(nilai <
root->value){
root->left =
insert(root->left,nilai);
}
return root;
}
Kita mengoper
root, dan nilai baru untuk node yang kita acari. Ketika root nya tidak ada atau
null, maka nilai itu akan menjadi root. Jika tidak, maka akan dilakukan
pengecekan nilai itu lebih besar atau lebih kecil dari root.
Jika lebih
besar dari root, maka akan diinsert ke root right. Sebaliknya jika lebih kecil
maka akan diinsert ke left, hingga ketemu NULL dan di create
Node *del(Node
*root, int nilai){
if(root==NULL) return NULL;
else{
if(nilai ==
root->value){
if(root->left==NULL
&& root->right==NULL){ //ga ada left right
free(root);
root
= NULL;
}
else
if(root->left==NULL){ //ada right
curr
= root;
root
= root->right;
free(curr);
curr
= NULL;
}
else
if(root->right==NULL){ /ada left
curr
= root;
root
= root->left;
free(curr);
curr
= NULL;
}
else{
//kalau 2 anak,
curr
= root->left; //dalam hal ini, dicari anak terkanan dari left root
while(curr->right){
curr
= curr->right;
}
root->value
= curr->value; //dilakukan penukaran nilai
root->left
= del(root->left,curr->value);
}
}
else if(nilai >
root->value){
root->right
= del(root->right,nilai);
}
else if(nilai <
root->value){
root->left
= del(root->left,nilai);
}
}
return root;
}
Deletion memiliki
3 kondisi
11. Node merupakan leaf / tidak ada left dan right
Dalam hal ini, node tinggal di free dan dijadikan
NULL
22. Node punya 1 anak , left atau right
Maka node digeser , dihubungkan dengan anak dan
node yang lama di free
33. Node punya dua anak, left dan right
Biasanya, ada kesepakatan mengenai
pengganti dari node, yaitu node paling kanan dari left atau node paling kiri
dari right, tergantung kesepakatan.
Tidak ada komentar:
Posting Komentar