0% found this document useful (0 votes)
7 views11 pages

2 Hashing

The document discusses different techniques for handling collisions in hashing, including separate chaining and open addressing. It provides details on linear probing, quadratic probing and double hashing as open addressing techniques. The aim is to implement insertion and searching in hashing using separate chaining and linear probing.

Uploaded by

Anver S R
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views11 pages

2 Hashing

The document discusses different techniques for handling collisions in hashing, including separate chaining and open addressing. It provides details on linear probing, quadratic probing and double hashing as open addressing techniques. The aim is to implement insertion and searching in hashing using separate chaining and linear probing.

Uploaded by

Anver S R
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Exercise No.

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.

Disadvantages of linear probing


1. The main problem is clustering.
2. It takes too much time to find an empty slot.
Quadratic probing
In this, when the collision occurs, we probe for i2th slot in ith iteration, and this probing is performed
until an empty slot is found. The cache performance in quadratic probing is lower than the linear
probing. Quadratic probing also reduces the problem of clustering.
Double hashing
In this, you use another hash function, and probe for (i * hash 2(x)) in the ith iteration. It takes longer
to determine two hash functions. The double probing gives the very poor the cache performance, but
there has no clustering problem in it.

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.

(a) Implementation of Hashing Separate Chaining:

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

typedef struct Hashtable


{
int key;
struct Hashtable * link;
}hashTable;

hashTable HT[size];

int hashCode(int key1)


{
return key1%size;
}

void initialHashtable()
{
int i;
for(i=0; i<size; i++)
HT[i].key = -999;
HT[i].link = NULL;
}

void insert(int key1)


{
int index;
hashTable * newnode;
index = hashCode(key1);
if(HT[index].key == -999)
{
HT[index].key = key1;
}
else
{
if(HT[index].link==NULL)
{
//create a newnode
newnode = (hashTable *)malloc(sizeof(hashTable));
newnode->key = key1;
newnode->link = NULL;
HT[index].link = newnode;
}
else
{
newnode = (hashTable *)malloc(sizeof(hashTable));
newnode->key = key1;
newnode->link = HT[index].link;
HT[index].link = newnode;

}
}
}

int search(int key1)


{
int i;
hashTable * ptr;
i= hashCode(key1);

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

(b) Implement hashing using Linear Probing:

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;

Algorithm 3: HashInsert(Insert_key, insert_data)


1. Index = Hashfunction(Insert_key);
2. If the slot is empty, insert key and data into the slot.
3. If collision occurs
4. Search through the hash table for empty slot, till index -1 in circular order.
5. Whenever an empty slot is obtained, insert the key and data there.
Program:

#include <stdio.h>
#include<stdlib.h>
#include<string.h>

#define size 10

typedef struct Hashtable


{
int key;
char data[20];
}hashTable;

hashTable HT[size];

int hashCode(int key1)


{
return key1%size;
}

void initialHashtable()
{
int i;
for(i=0; i<size; i++)
HT[i].key = -999;
strcmp(HT[i].data,"NULL");
}

void insert(int key1, char data1[])


{
int index, till_index;

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;

int search(int key1)


{
int i, till_i;

i= hashCode(key1);
till_i=(i-1+size)%size;

while ((HT[i].key != -999)&&(i!=till_i))


{
if(HT[i].key == key1) return 1;
i = (i+1)%size;
}
if((i== till_i)&&(HT[i].key == key1))
return 1;
return 0;
}

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:

Enter your option *** 1: insert 2: Search 3: Display *** :: 1


Enter the key to be inserted :: 89
Enter the data to be inserted :: jaya
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 :: 19
Enter the data to be inserted :: amit
You want to continue?? 1: continue 0: exit :: 1
Enter your option *** 1: insert 2: Search 3: Display *** :: 3
19 | amit
-999 |
-999 |
-999 |
-999 |
-999 |
-999 |
-999 |
-999 |
89 | jaya

You want to continue?? 1: continue 0: exit :: 0


Result:
Hash table is implemented with Separate chaining and linear addressing, and Searching and Insertion
operations are performed and the output is verified.

You might also like