Apa itu Hash Table?
Hash Table adalah struktur data yang digunakan untuk mengimplementasikan array asosiatif atau mapping, di mana data disimpan dalam pasangan key-value. Key digunakan untuk mengindeks value dan mempercepat pencarian dan pengambilan data.
Implementasi Hash Table didasarkan pada fungsi hash, yang mengubah key menjadi indeks dalam array. Pada implementasi yang baik, fungsi hash harus menghasilkan indeks yang unik untuk setiap key.
Notes
- Sebuah hash function digunakan untuk mengubah key menjadi indeks dalam array yang digunakan untuk menyimpan value.
- Hash function harus memberikan hasil yang unik untuk setiap key yang berbeda.
- Hash table dapat digunakan untuk mempercepat pencarian data, karena data dapat diakses dengan cepat berdasarkan key yang diberikan.
- Beberapa cara untuk menangani tabrakan dalam hash table adalah dengan separate chaining, linear probing, dan quadratic probing.
Ilustrasi
Berikut adalah visualisasi sebuah hash table dengan size 4,
Kita menggunakan hashing function f(x) = x % 4 (SIZE), maka value 21 menjadi index 1, value 23 menjadi 3
Dengan implementasi separate chaining, maka value baru 41 dengan key yang sama di index 1, menjadi di sebelah 21
Dengan implementasi linear probing, maka value baru 41 dengan key yang sama di index 1 menjadi di tempat selanjutnya yaitu index 2
Kita bisa melihat bahwa dengan implementasi linear probing, ada kemungkinan value baru tidak dapat ditampung lagi, karena berbeda dari separate chaining yang tidak memakai space array namun dirantai di sebelah value sebelumnya.
Linear probing akan membuat size array dikali 2 di implementasi library ketika sudah full, namun pada implementasi kita dibawah hanya akan mengatakan bahwa array sudah full.
Implementasi
Separate Chaining
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 10 // Ukuran array untuk hash table
// Struktur node untuk linked list pada setiap elemen array hash table
typedef struct node {
char* key;
int value;
struct node* next;
} node;
// Fungsi hash untuk menghasilkan indeks dari kunci yang diberikan
int hash(char* key) {
int sum = 0;
for (int i = 0; i < strlen(key); i++) {
sum += (int) key[i];
}
return sum % MAX_SIZE;
}
// Fungsi untuk membuat node baru
node* create_node(char* key, int value) {
node* new_node = malloc(sizeof(node));
new_node->key = key;
new_node->value = value;
new_node->next = NULL;
return new_node;
}
// Fungsi untuk memasukkan data ke dalam hash table
void insert(node** hash_table, char* key, int value) {
int index = hash(key);
node* new_node = create_node(key, value);
if (hash_table[index] == NULL) {
hash_table[index] = new_node;
} else {
node* current_node = hash_table[index];
while (current_node->next != NULL) {
current_node = current_node->next;
}
current_node->next = new_node;
}
}
// Fungsi untuk mencari nilai dari kunci yang diberikan
int search(node** hash_table, char* key) {
int index = hash(key);
node* current_node = hash_table[index];
while (current_node != NULL) {
if (strcmp(current_node->key, key) == 0) {
return current_node->value;
}
current_node = current_node->next;
}
return -1; // Nilai kunci tidak ditemukan
}
// Fungsi untuk menampilkan seluruh data dalam hash table
void display(node** hash_table) {
for (int i = 0; i < MAX_SIZE; i++) {
printf("[%d]: ", i);
node* current_node = hash_table[i];
while (current_node != NULL) {
printf("(%s, %d) ", current_node->key, current_node->value);
current_node = current_node->next;
}
printf("\n");
}
}
int main() {
node* hash_table[MAX_SIZE] = { NULL }; // Inisialisasi hash table dengan NULL
// Memasukkan data ke dalam hash table
insert(hash_table, "apple", 5);
insert(hash_table, "banana", 2);
insert(hash_table, "cherry", 9);
insert(hash_table, "durian", 7);
// Menampilkan data dalam hash table
printf("Hash table:\n");
display(hash_table);
// Mencari nilai dari kunci yang diberikan
printf("\n");
printf("Value of 'apple': %d\n", search(hash_table, "apple"));
printf("Value of 'banana': %d\n", search(hash_table, "banana"));
printf("Value of 'cherry': %d\n", search(hash_table, "cherry"));
printf("Value of 'durian': %d\n", search(hash_table, "durian"));
}
Output
Hash table:
[0]: (apple, 5)
[1]:
[2]:
[3]: (cherry, 9) (durian, 7)
[4]:
[5]:
[6]:
[7]:
[8]:
[9]: (banana, 2)
Value of 'apple': 5
Value of 'banana': 2
Value of 'cherry': 9
Value of 'durian': 7
Linear Probing
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 10 // Ukuran array untuk hash table
// Struktur untuk setiap elemen dalam hash table
typedef struct {
char* key;
int value;
} element;
// Struktur untuk hash table
typedef struct {
element table[MAX_SIZE];
} hash_table;
// Fungsi hash untuk menghasilkan indeks dari kunci yang diberikan
int hash(char* key) {
int sum = 0;
for (int i = 0; i < strlen(key); i++) {
sum += (int) key[i];
}
return sum % MAX_SIZE;
}
// Fungsi untuk memasukkan data ke dalam hash table
void insert(hash_table* ht, char* key, int value) {
int index = hash(key);
int count = 0; // Menghitung jumlah iterasi yang dilakukan
while (ht->table[index].key != NULL && strcmp(ht->table[index].key, key) != 0) {
index = (index + 1) % MAX_SIZE; // Linier probing
count++;
if (count == MAX_SIZE) {
printf("Hash table is full\n");
return;
}
}
ht->table[index].key = key;
ht->table[index].value = value;
}
// Fungsi untuk mencari nilai dari kunci yang diberikan
int search(hash_table* ht, char* key) {
int index = hash(key);
int count = 0; // Menghitung jumlah iterasi yang dilakukan
while (ht->table[index].key != NULL && strcmp(ht->table[index].key, key) != 0) {
index = (index + 1) % MAX_SIZE; // Linier probing
count++;
if (count == MAX_SIZE) {
return -1; // Nilai kunci tidak ditemukan
}
}
if (ht->table[index].key == NULL) {
return -1; // Nilai kunci tidak ditemukan
} else {
return ht->table[index].value;
}
}
// Fungsi untuk menampilkan seluruh data dalam hash table
void display(hash_table* ht) {
for (int i = 0; i < MAX_SIZE; i++) {
printf("[%d]: ", i);
if (ht->table[i].key == NULL) {
printf("NULL\n");
} else {
printf("(%s, %d)\n", ht->table[i].key, ht->table[i].value);
}
}
}
int main() {
hash_table ht = { 0 }; // Inisialisasi hash table dengan NULL
// Memasukkan data ke dalam hash table
insert(&ht, "apple", 5);
insert(&ht, "banana", 2);
insert(&ht, "cherry", 9);
insert(&ht, "durian", 7);
insert(&ht, "elderberry", 3);
// Menampilkan data dalam hash table
printf("Hash table:\n");
display(&ht);
// Mencari nilai dari kunci yang diberikan
printf("\n");
printf("Value of 'apple': %d\n", search(&ht, "apple"));
printf("Value of 'banana': %d\n", search(&ht, "banana"));
}
Output
Hash table:
[0]: (apple, 5)
[1]: NULL
[2]: (elderberry, 3)
[3]: (cherry, 9)
[4]: (durian, 7)
[5]: NULL
[6]: NULL
[7]: NULL
[8]: NULL
[9]: (banana, 2)
Value of 'apple': 5
Value of 'banana': 2