2 Hashing
2 Hashing
2
Implementation of Hashing
Hashing::
Hashing is the process of converting a given key into another value. A hash function is used to
generate the new value according to a mathematical algorithm. The result of a hash function is
known as a hash value or simply, a hash.
In this, the hash function is used to compute the index of the array.
The hash value is used to store the key in the hash table, as an index.
Collision:
The hash function can return the same hash value for two or more keys.
When two or more keys are given the same hash value, it is called a collision. That is, for some k1
and k2, h(k1) == h(k2).
To handle this collision, we use collision resolution techniques.
Collision resolution techniques
There are two types of collision resolution techniques.
1. Separate chaining (open hashing)
2. Open addressing (closed hashing)
Separate Chaining (Open Hashing)
In this technique, a linked list is created from the slot in which collision has occurred, after which the
new key is inserted into the linked list. This linked list of slots looks like a chain, so it is
called separate chaining. It is used more when we do not know how many keys to insert or delete.
Advantages of separate chaining
1. It is easy to implement.
2. The hash table never fills full, so we can add more elements to the chain.
3. It is less sensitive to the function of the hashing.
Disadvantages of separate chaining
1. The memory wastage is too much in this method.
2. It requires more space for element links.
Open addressing
Open addressing is collision-resolution method that is used to control the collision in the hashing
table. There is no key stored outside of the hash table. Therefore, the size of the hash table is always
greater than or equal to the number of keys. It is also called closed hashing.
The following techniques are used in open addressing:
1. Linear probing
2. Quadratic probing
3. Double hashing
Linear probing
In this, when the collision occurs, we perform a linear probe for the next slot, and this probing is
performed until an empty slot is found. In linear probing, the worst time to search for an element is
O(table size). The linear probing gives the best performance of the cache but its problem is
clustering. The main advantage of this technique is that it can be easily calculated.
Aim:
Implement Insertion and Searching in Hashing using the hash function h(k) = k % size.
(a) Use the method of Separate chaining for collision resolution.
(b) Use Linear Probing for collision Resolution.
Input:
Hash table of size “size”.
The key to be inserted or to be searched.
Output:
The key is found or not (in case of searching).
The key inserted into the hash table (in case of insertion).
Algorithm:
Algorithm 1: Hashfunction(key)
1. return key % size;
Algorithm 2: HashSearch(Search_key)
1. Index = Hashfunction(Search_key);
2. if(HT[index].key == Search_key) return true;
3. Else
4. ptr = HT[i].link;
5. while(ptr!=NULL)
6. if(ptr->key == key1) return 1;
7. ptr = ptr->link;
8. return 0;
Algorithm 3: HashInsert(Insert_key)
1. Index = Hashfunction(Insert_key);
2. If collision occurs
3. .Create a newnode;
4. Fill key field
5. If linked list already exists
6. Insert the newnode to the beginning of the existing linked list.
7. Else
8. Create a linked list with the newnode.
9. Else
10. Insert the Insert_key into the table itself.
Program:
#include <stdio.h>
#include<stdlib.h>
#define size 10
hashTable HT[size];
void initialHashtable()
{
int i;
for(i=0; i<size; i++)
HT[i].key = -999;
HT[i].link = NULL;
}
}
}
}
if(HT[i].key == key1)
return 1;
else
{
ptr = HT[i].link;
while(ptr!=NULL)
{
if(ptr->key == key1) return 1;
ptr = ptr->link;
}
}
return 0;
}
void hashDisplay()
{
int i;
hashTable * ptr;
for(i=0; i<size; i++)
{
printf("%d", HT[i].key);
ptr = HT[i].link;
while(ptr!=NULL)
{
printf(" -> %d", ptr->key);
ptr = ptr->link;
}
printf("\n");
}
}
int main()
{
int key1, k;
initialHashtable();
int option;
int choice=1;
while(choice)
{
printf("Enter your option *** 1: insert 2: Search 3: Display *** :: ");
scanf("%d", &option);
switch(option)
{
case 1:
printf("Enter the key to be inserted :: ");
scanf("%d", &key1);
insert(key1);
break;
case 2:
printf("Enter the key to be Searched :: ");
scanf("%d", &key1);
k=search(key1);
if(k==1) printf("Search key is found \n");
break;
case 3:
hashDisplay();
break;
default:
printf("\n ##### Wrong Choice !!! #### \n");
}
printf("You want to continue?? 1: continue 0: exit :: ");
scanf("%d", &choice);
}
}
Sample Output:
Enter your option *** 1: insert 2: Search 3: Display *** :: 1
Enter the key to be inserted :: 12
You want to continue?? 1: continue 0: exit :: 1
Enter your option *** 1: insert 2: Search 3: Display *** :: 1
Enter the key to be inserted :: 59
You want to continue?? 1: continue 0: exit :: 1
Enter your option *** 1: insert 2: Search 3: Display *** :: 1
Enter the key to be inserted :: 89
You want to continue?? 1: continue 0: exit :: 1
Enter your option *** 1: insert 2: Search 3: Display *** :: 3
-999
-999
12
-999
-999
-999
-999
-999
-999
59 ->89
You want to continue?? 1: continue 0: exit :: 1
Enter your option *** 1: insert 2: Search 3: Display *** :: 2
Enter the key to be Searched :: 89
Search key is found
You want to continue?? 1: continue 0: exit :: 0
Input:
Hash table of size “size”.
The key along with the data to be inserted(for insertion).
The key alone, in case of searching.
Output:
The key is found or not (in case of searching).
The key and data inserted into the hash table (in case of insertion) using linear probing.
Algorithm:
Algorithm 1: Hashfunction(key)
1. return key % size;
Algorithm 2: HashSearch(Search_key)
1. Index = Hashfunction(Search_key);
2. Set till_index as Index – 1 in Circular order
3. While ((HT[Index]!=Search_key) && (Index != till_index))
4. Index = index + 1 (in circular order)
5. If (HT[index]==search_key)
6. return 1;
7. return 0;
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define size 10
hashTable HT[size];
void initialHashtable()
{
int i;
for(i=0; i<size; i++)
HT[i].key = -999;
strcmp(HT[i].data,"NULL");
}
index = hashCode(key1);
till_index=(index-1+size)%size;
while ((HT[index].key != -999)&&(index!=till_index))
{
index = (index+1)%size;
}
if((HT[index].key == -999)&&((index==till_index)||(index!=till_index)))
{
HT[index].key = key1;
strcpy(HT[index].data, data1);
}
else
{
printf("No space for new data");
}
return;
i= hashCode(key1);
till_i=(i-1+size)%size;
void hashDisplay()
{
int i;
hashTable * ptr;
for(i=0; i<size; i++)
{
printf("%d | %s ", HT[i].key, HT[i].data);
printf("\n");
}
}
int main()
{
int key1, k;
char data1[20];
initialHashtable();
int option;
int choice=1;
while(choice)
{
printf("Enter your option *** 1: insert 2: Search 3: Display *** :: ");
scanf("%d", &option);
switch(option)
{
case 1:
printf("Enter the key to be inserted :: ");
scanf("%d", &key1);
printf("Enter the data to be inserted :: ");
scanf("%s]", data1);
insert(key1, data1);
break;
case 2:
printf("Enter the key to be Searched :: ");
scanf("%d", &key1);
k=search(key1);
if(k==1) printf("Search key is found \n");
else printf("Search key is found \n");
break;
case 3:
hashDisplay();
break;
default:
printf("\n ##### Wrong Choice !!! #### \n");
}
printf("You want to continue?? 1: continue 0: exit :: ");
scanf("%d", &choice);
}
}
Sample Output: