Hashing & Hash Tables
Hashing
Hashing adalah teeknik yang digunakan untuk
menyimpan dan mengambil kunci dengan cepat. Tujuan hashing adalah sebagai
metode untuk menyimpan data dalam sebuah array agar penyimpanan data, pencarian
data, penambahan datam dan penghapusan data dapat dilakukan dengan cepat.
Hash Table
Hash table adalah salah satu struktur data
yang digunakan dalam penyimpanan data sementara. Hash table menggunakan memori
penyimpanan utama berbentyj array dengan tambahan algoritma untuk mempercepat
pemrosesan data.
Hash
Function
Hash Function adalah suatu fungsi sederhana
untuk mendaoatkan nilai hash dari nilai kunci(key value) suatu data.
Ada beberapa hal dalam membuat hash function
antara lain :
·
Ukuran
array/ table size (m)
·
Key
value/ nilai yang di dapat dari data (k)
·
Hash
value/ hash index/index yang dituju (h)
Beberapa metode pentuk untuk membangun hash
functions antara lain:
- Mid – square
- Division
(most common)
- Folding
- Digit Extraction
- Rotating Hash
Mid – square
Mid-Square hashing adalah teknik hashing di
mana kunci unik dihasilkan. Dalam teknik ini, nilai benih diambil dan
dikuadratkan. Kemudian, beberapa digit dari tengah diekstraksi. Angka-angka
yang diekstrak ini membentuk angka yang diambil sebagai benih baru. Teknik ini
dapat menghasilkan kunci dengan keacakan tinggi jika nilai benih yang cukup
besar diambil. Namun, itu memiliki batasan. Saat bijinya dikuadratkan, jika
angka 6-digit diambil, maka persegi akan memiliki 12-digit. Ini melebihi
kisaran tipe data int. Jadi, overflow harus diurus. Jika terjadi overflow,
gunakan tipe data int panjang atau gunakan string sebagai perkalian jika luapan
masih terjadi. Kemungkinan tabrakan di tengah-tengah hashing rendah, tidak
usang. Jadi, dalam peluang, jika tabrakan terjadi, itu ditangani menggunakan
beberapa peta hash.
Contoh:
Nilai
|
Di
kuadratkan
|
Nilai di
ekstraksi
|
4765
|
22705225
|
7052
|
3725
|
13875625
|
8756
|
Algoritma dalam mid – square
- Pilih nilai seed. Ini adalah langkah penting karena untuk nilai seed yang sama, urutan nomor acak yang sama dihasilkan.
- Ambil kuadrat dari nilai seed dan perbarui seed dengan jumlah digit tertentu yang terjadi di square. Catatan: Semakin besar jumlah digit, semakin besar keacakannya.
- Kembalikan kuncinya.
Division
Jumlah lokasi memori tersedia dihitung ,
kemudian jumlah tersebut digunakan sebagai pembagi untuk membagi nilai yang
asli dan menghasilkan sisa(nilai hashnya).
Secara umum rumus division sebagai berikut :
h(z) = z mod
M
Keterangan:
z
= key/ suatu lokasi memori yang beralamat h(z)
M
= jumlah lokasi memori yang
tersedia pada array
Contoh:
Ukuran
table = 97
COBB
Abjad
|
Nilai ASCII
|
C
|
67
|
O
|
79
|
B
|
66
|
B
|
66
|
total
|
278
|
H(z) = 278 mod 97 = 84
HIKE
Abjad
|
Nilai ASCII
|
H
|
72
|
I
|
73
|
K
|
75
|
E
|
69
|
total
|
289
|
H(z) = 289 mod 97 = 95
ABCD
Abjad
|
Nilai ASCII
|
A
|
65
|
B
|
66
|
C
|
67
|
D
|
68
|
total
|
266
|
H(z) = 278 mod 97 = 72
Folding
Metode
lipat berfungsi dalam 2 langkah :
- Bagi nilai kunci menjadi beberapa bagian dimana setiap bagian memiliki jumlah digit yang sama kecuali bagian terakhir yang mungkin memiliki angka lebih sedikit daripada bagian lainnya.
- Tambahan bagi individu. Yaitu memperoleh jumlah part 1 + part + .. + part n. Nilai hash yang dihasilkan dengan mengabaikan carry terakhir, jika ada.
Contoh:
Key = 6632
Parts = 66 dan 32
Jumlah = 98
Hash value = 98
Digit
Extraction
Mendapatkan
hash key dengan cara mengambil digit – digit tertentu dari sebuah string
untuk
dijadikan hash keynya.
Contoh:
terdapat string yaitu 14568, jika kita mengambil digit 1, digit 3, dan digit 5
maka
hash keynya adalah 158.
Rotating
Hash
Mendapatkan
hash key maka di lakukan rotasi untuk menggeser digit sehingga
menemukan alamat
hash key baru.
Contoh
:
Hash
key = 3456
Hasil
rotasi = 6543
Collision
Ada 2 cara untuk menangani collision :
·
Linear
Probing
Mencari
slot kosong berikutnya dan letakkan string disana.
Code
:
void linear_probing(item, h[]) {
hash_key = hash(item);
i = has_key;
while ( strlen(h[i] != 0 ) {
if ( strcmp(h[i],
item) == 0 ) {
// DUPLICATE
ENTRY
}
}
i = (i + 1) %
TABLE_SIZE;
if ( i == hash_key )
{
// TABLE IS FULL
}
}
}
}
h[i] = item;
}
}
·
Chaining
Masukkan
string ke dalam slot sebagai chained list(linked list).
Code:
void chaining(item, h[]) {
hash_key = hash(item);
trail = NULL, lead =
h[hash_key];
while ( lead ) {
if (
strcmp(lead->item, item) == 0 ) { // DUPLICATE ENTRY }
trail = lead; lead =
lead->next;
}
}
p = malloc new node;
p->item = item;
p->next = NULL;
if ( trail == 0 )
h[hash_key] = p; else trail->next = p;
}
Trees & Binary
Tree
Tree adalah
salah satu bentuk struktur data tidak linear yang menggambarkan hubungan yang
bersifat hirarkis (hubungan one to many) antara elemen-elemen. Tree bisa
didefinisikan sebagai kumpulan simpul/node dengan satu elemen khusus yang
disebut Root dan node lainnya terbagi menjadi himpunan-himpunan yang saling tak
berhubungan satu sama lainnya (disebut subtree).
Istilah –
istilah umum dalam tree :
·
Prodecessor : node yang berada diatas node
tertentu.
·
Successor : node yang berada di bawah 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 : predecssor 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 punya predecssor.
·
Leaf : node-node dalam tree yang tak memiliki
seccessor.
·
Degree : banyaknya child yang dimiliki suatu
node.
Jenis – jenis
binary tree:
·
Perfect binary tree
Adalah
binary tree yang setiap level berada pada kedalaman/ depth yang sama.
·
Complete binary tree
Adalah
binary tree yang setiap levelnya kecuali yang terakhir semua telah terisi penuh
dan setiap nodesnya paling panjang ke kiri.
·
Skewed binary tree
Adalah
binary tree yang semua nodenya (kecuali leaf) hanya memiliki satu child.
·
Balanced binary tree
Adalah
binary tree yang dimana yang setiap leafnya sama jauhnya dari root
Representation of Binary Tree
- Implementation using array
Index on array represents node number
Index 0 is Root node
Index Left Child is 2p + 1, where p is
parent index
Index Right Child is 2p + 2
Index Parent is (p-1)/2
- Implementation using linked list
struct node {
int data;
struct node *left;
struct node *right;
struct node *parent;
};
struct node *root = NULL;
structure binary tree
struct tnode {
char chr;
struct tnode *left;
struct tnode *right;
};
Insert di binary tree mengunakan C
// C++ program to insert element in binary tree
#include <iostream>
#include <queue>
using
namespace
std;
/* A binary tree node has key, pointer to left child
and a pointer to right child */
struct
Node {
int key;
struct Node*
left, *right;
};
/* function to create a new node of tree and r
eturns pointer */
struct
Node* newNode(int key)
{
struct Node* temp
= new Node;
temp->key = key;
temp->left = temp->right =
NULL;
return temp;
};
/* Inorder traversal of a binary tree*/
void
inorder(struct Node* temp)
{
if (!temp)
return;
inorder(temp->left);
cout << temp->key <<
" ";
inorder(temp->right);
}
/*function to insert element in binary tree */
void
insert(struct Node* temp, int key)
{
queue<struct Node*>
q;
q.push(temp);
// Do level order traversal until we
find
// an empty place.
while (!q.empty())
{
struct Node* temp
= q.front();
q.pop();
if (!temp->left)
{
temp->left
= newNode(key);
break;
} else
q.push(temp->left);
if (!temp->right)
{
temp->right
= newNode(key);
break;
} else
q.push(temp->right);
}
}
// Driver code
int
main()
{
struct Node* root
= newNode(10);
root->left = newNode(11);
root->left->left = newNode(7);
root->right = newNode(9);
root->right->left =
newNode(15);
root->right->right =
newNode(8);
cout << "Inorder
traversal before insertion:";
inorder(root);
int key = 12;
insert(root, key);
cout << endl;
cout << "Inorder
traversal after insertion:";
inorder(root);
return 0;
}
Deletion in a Binary Tree
Given a binary tree, delete a node from it by
making sure that tree shrinks from the bottom (i.e. the deleted node is
replaced by bottom most and rightmost node). This different from BST deletion.
Here we do not have any order among elements, so we replace with last element.
Contoh:
Delete 10 in below tree
10
/ \
20 30
Output :
30
/
20
Delete 20 in below tree
10
/ \
20 30
\
40
Output :
10
/ \
40 30
Algorithm
·
Starting
at root, find the deepest and rightmost node in binary tree and node which we
want to delete.
·
Replace
the deepest rightmost node’s data with node to be deleted.
·
Then
delete the deepest rightmost node.
Source code in C/C++
// C++ program to delete element in binary tree
#include <bits/stdc++.h>
using
namespace
std;
/* A binary tree node has key, pointer to left
child and a pointer to right child */
struct
Node {
int key;
struct Node
*left, *right;
};
/* function to create a new node of tree and
return pointer */
struct
Node* newNode(int key)
{
struct Node* temp
= new Node;
temp->key = key;
temp->left = temp->right =
NULL;
return temp;
};
/* Inorder traversal of a binary tree*/
void
inorder(struct Node* temp)
{
if (!temp)
return;
inorder(temp->left);
cout << temp->key <<
" ";
inorder(temp->right);
}
/* function to delete the given deepest node
(d_node) in binary tree */
void
deletDeepest(struct Node* root,
struct Node*
d_node)
{
queue<struct Node*>
q;
q.push(root);
// Do level order traversal until
last node
struct Node*
temp;
while (!q.empty())
{
temp =
q.front();
q.pop();
if (temp ==
d_node) {
temp
= NULL;
delete (d_node);
return;
}
if (temp->right)
{
if (temp->right
== d_node) {
temp->right
= NULL;
delete (d_node);
return;
}
else
q.push(temp->right);
}
if (temp->left)
{
if (temp->left
== d_node) {
temp->left
= NULL;
delete (d_node);
return;
}
else
q.push(temp->left);
}
}
}
/* function to delete element in binary tree */
Node* deletion(struct Node* root, int key)
{
if (root ==
NULL)
return NULL;
if (root->left
== NULL && root->right == NULL) {
if (root->key
== key)
return NULL;
else
return root;
}
queue<struct Node*>
q;
q.push(root);
struct Node*
temp;
struct Node* key_node
= NULL;
// Do level order traversal to find
deepest
// node(temp) and node to be deleted
(key_node)
while (!q.empty())
{
temp =
q.front();
q.pop();
if (temp->key
== key)
key_node
= temp;
if (temp->left)
q.push(temp->left);
if (temp->right)
q.push(temp->right);
}
if (key_node
!= NULL) {
int x =
temp->key;
deletDeepest(root,
temp);
key_node->key
= x;
}
return root;
}
// Driver code
int
main()
{
struct Node* root
= newNode(10);
root->left = newNode(11);
root->left->left = newNode(7);
root->left->right =
newNode(12);
root->right = newNode(9);
root->right->left =
newNode(15);
root->right->right =
newNode(8);
cout << "Inorder
traversal before deletion : ";
inorder(root);
int key = 11;
root = deletion(root, key);
cout << endl;
cout << "Inorder
traversal after deletion : ";
inorder(root);
return 0;
}
materi binus
https://www.geeksforgeeks.org/mid-square-hashing/
https://www.geeksforgeeks.org/insertion-in-a-binary-tree-in-level-order/
https://www.geeksforgeeks.org/deletion-binary-tree/
http://new-funday.blogspot.com/2012/12/struktur-data-tree-dan-penjelasaanya.html
https://zoneblog123.blogspot.com/2018/04/pengertian-tree-binary-tree-beserta.html
Tidak ada komentar:
Posting Komentar