Hash Table
Hash table kind of data structure that use an associative array, meaning that a hash table can map a value to a certain index/key. Usually this will use a hash function to find out to index/key of a certain value. Hash Table is used speed up searching so that it can reach O(n). In hash table we will find two new term such as :- Collision : Is where our hash function generate the same key for two different value. Usually such collision will be handled with some kind of collision handling in the code.
- Hash Function : A function that will generate key for a value.
Hash Function
A hash function is usually used to find out the key or index of a certain value. This key will be sued to insert our data into the table. Also there is no hash function that will not generate any collision, meaning that our code will have to be able to handle collision. There are many method that can be used to generate hash key :- Division : a Mod b (a is our value, b is the size of our table usually a prime number)
- Multiplication : floor ( n ( k A mode 1))
- n : is the size of out table
- k : is the value
- A : is a random number between 0 and 1
- etc.
Collision
Collision is caused by a hash function that generate a same key for 2 or more different value. Usually this will be resolved in two different way :
- Separate Chaining
In separate chaining if there are a collision the inserted data will be chained to the old data like a linked list (https://en.wikipedia.org/wiki/Hash_table#Collision_resolution)

- Open Addressing
Is where we compute the key again so that we will get an empty space in our table. There are 3 usually used method for this type :
- Linear Probing : Is where we add 1 to our key until we get an empty space in the table
- Quadratic Probing : Is where we add successive value(1,2,3,...) to our key until we get an empty space in out table.
- Double Hashing : where we rehash out key with a different hash function.
Below is a code for a hash table with separate chaining to resolve the collision :
#include <stdio.h>
#include <malloc.h> //we need to use malloc to create a new node
#define SIZE 20
struct Node{
int value; //using the separate chaining concept to address collision
Node *next;
};
Node *table[SIZE]; // make out table (can only accept pointer)
Node *createNode(int val){
Node *node = (Node*)malloc(sizeof(Node));
node->value=val; // function to make a new node
node->next=NULL;
return node;
}
int hash(int value){
return value % SIZE; //our hash function
}
void insert(int val){
Node *node=createNode(val);
int key = hash(node->value);
if(table[key]==NULL){
table[key]=node; //if the table is null then just insert
}else {
if(table[key]->next==NULL){
table[key]->next=node;
}else { //use separate chaining for collision handling
Node *curr=table[key];
while(curr->next!=NULL){
curr=curr->next;
}
curr->next=node;
}
}
}
void del(int val){
int key = hash(val);
if(table[key]==NULL){
return ;
}else{
if(table[key]->value==val){
if(table[key]->next==NULL){
table[key]=NULL;
}else {
Node *del = table[key];
table[key]=table[key]->next;
free(del);
del = NULL;
}
}else {
Node *del=table[key]->next;
Node *prev=table[key];
while(del->value!=val && del!=NULL){
del = del->next;
prev = prev->next;
}
prev->next = del->next;
free(del);
del=NULL;
}
}
}
void init(){
for(int i=0;i<SIZE;i++){
table[i] = NULL; //function to initialize out table;
}
}
void view(){
for(int i=0;i<SIZE;i++){
if(i+1<10){
printf("%d | ", i+1);
}else {
printf("%d | ", i+1);
}
Node *curr=table[i];
while(curr!=NULL){ //function to view our table
printf("%d -> ", curr->value);
curr=curr->next;
}
printf("\n");
}
}
void cls(){
for(int i=0;i<35;i++){
printf("\n");
}
}
int main(){
int input;
int menu;
init();
while(1){
cls();
view();
printf("1. Insert\n");
printf("2. Delete\n");
printf("3. Exit\n");
printf(">> ");
scanf("%d", &menu); getchar();
if(menu==3){
break;
}
switch(menu){
case 1:
printf("Insert data : ");
scanf("%d", &input);
insert(input);
break;
case 2:
printf("Input data : ");
scanf("%d", &input);
del(input);
break;
}
}
return 0;
}
Comments
Post a Comment