C Program to Implement Hash Tables with Double Hashing

«
»

This is a C Program to implement Hash Tables with Double Hashing.

Problem Description

A hash table is a data structure used to implement an associative array, a structure that can map keys to values. A hash table uses a hash function to compute an index into an array of buckets or slots. To prevent the collision of two keys ,the idea of Double Hashing is used. In case any collision occurs when we just use traditional hash code evaluating function, another hash code is generated by some other function and both the hash codes are used to find a free space by probing through array elements.

Problem Solution

1. Create an array of structure (i.e a hash table).
2. Take a key and a value to be stored in hash table as input.
3. Corresponding to the key, an index will be generated i.e every key is stored in a particular array index.
4. Using the generated index, access the data located in that array index.
5. In case of absence of data, create one and insert the data item (key and value) into it and increment the size of hash table.
6. In case the data exists, probe through the subsequent elements (looping back if necessary) for free space to insert new data item.
Note: Here, unlike quadratic and linear probing, we will first calculate another hash code of same key using formula-: hashcode2 = primeNum – (key % primeNum) , where primeNum is largest prime number less that array size
Probing formula after calculating hashcode2 -:
(hashcode1 + (h * hashcode2)) % arraySize , h = 1, 2, 3, 4 and so on
7. To display all the elements of hash table, element at each index is accessed (via for loop).
8. To remove a key from hash table, we will first calculate its index and delete it if key matches, else probe through elements (using above formula) until we find key or an empty space where not a single data has been entered (means data does not exist in the hash table).
9. Exit

advertisement
Program/Source Code

Here is the source code of C Program to implement a Hash Table with Double Hashing. The program is successfully compiled and tested using Turbo C compiler in windows environment. The program output is also shown below.

  1. #include<stdio.h>
  2. #include<conio.h>
  3. #include<math.h>
  4.  
  5. struct data 
  6. {
  7. 	int key;
  8. 	int value;
  9. };
  10.  
  11. struct hashtable_item 
  12. {
  13.  
  14. 	int flag;
  15. 	/*
  16. 	 * flag = 0 : data not present
  17. 	 * flag = 1 : some data already present
  18. 	 * flag = 2 : data was present,but deleted
  19. 	*/
  20. 	struct data *item;
  21.  
  22. };
  23.  
  24. struct hashtable_item *array;
  25. int max = 7;
  26. int size = 0;
  27. int prime = 3;
  28.  
  29. int hashcode1(int key)
  30. {
  31. 	return (key % max);
  32. }
  33.  
  34. int hashcode2(int key)
  35. {
  36. 	return (prime - (key % prime));
  37. }
  38.  
  39. void insert(int key, int value)
  40. {
  41. 	int hash1 = hashcode1(key);
  42. 	int hash2 = hashcode2(key);
  43.  
  44. 	int index = hash1;
  45.  
  46. 	/* create new data to insert */
  47. 	struct data *new_item = (struct data*) malloc(sizeof(struct data));
  48. 	new_item->key = key;
  49. 	new_item->value = value;
  50.  
  51. 	if (size == max) 
  52.         {
  53. 		printf("\n Hash Table is full, cannot insert more items \n");
  54. 		return;
  55. 	}
  56.  
  57. 	/* probing through other array elements */
  58. 	while (array[index].flag == 1) {
  59. 		if (array[index].item->key == key)
  60.                 {
  61. 			printf("\n Key already present, hence updating its value \n");
  62. 			array[index].item->value = value;
  63. 			return;
  64. 		}
  65. 		index = (index + hash2) % max; 
  66. 		if (index == hash1)
  67.                 {
  68. 			printf("\n Add is failed \n");
  69. 			return;
  70. 		}
  71. 		printf("\n probing \n");
  72.  
  73. 	}
  74.  
  75. 	array[index].item = new_item;
  76. 	array[index].flag = 1;
  77. 	size++;
  78. 	printf("\n Key (%d) has been inserted \n", key);
  79.  
  80. }
  81.  
  82. /* to remove an element from the array */
  83. void remove_element(int key)
  84. {
  85. 	int hash1 = hashcode1(key);
  86. 	int hash2 = hashcode2(key);
  87. 	int index = hash1;
  88.  
  89. 	if (size == 0)
  90.         {
  91. 		printf("\n Hash Table is empty \n");
  92. 		return;
  93. 	}
  94.  
  95. 	/* probing through other elements */
  96. 	while (array[index].flag != 0)
  97.         {
  98. 		if (array[index].flag == 1  &&  array[index].item->key == key)
  99.                 {
  100. 			array[index].item = NULL;
  101. 			array[index].flag = 2;
  102. 			size--;
  103. 			printf("\n Key (%d) has been removed \n", key);
  104. 			return;
  105. 		}
  106. 		index = (index + hash2) % max;
  107. 		if (index == hash1)
  108.                 {
  109. 			break;
  110. 		}
  111. 	}
  112.  
  113. 	printf("\n Key (%d) does not exist \n", key);
  114.  
  115. }
  116.  
  117. int size_of_hashtable()
  118. {
  119. 	return size;
  120. }
  121.  
  122. /* displays all elements of array */
  123. void display()
  124. {
  125. 	int i;
  126. 	for (i = 0; i < max; i++)
  127.         {
  128. 		if (array[i].flag != 1)
  129.                 {
  130. 			printf("\n Array[%d] has no elements \n", i);
  131. 		}
  132. 		else
  133.                 {
  134. 			printf("\n Array[%d] has elements \n Key (%d) and Value (%d) \n", i, array[i].item->key, array[i].item->value);
  135. 		}
  136. 	}
  137. }
  138.  
  139. /* initializes array */
  140. void init_array()
  141. {
  142. 	int i;
  143. 	for(i = 0; i < max; i++)
  144.         {
  145. 		array[i].item = NULL;
  146. 		array[i].flag = 0;
  147. 	}
  148. 	prime = get_prime();
  149. }
  150.  
  151. /* returns largest prime number less than size of array */
  152. int get_prime()
  153. {
  154. 	int i,j;
  155. 	for (i = max - 1; i >= 1; i--)
  156.         {
  157. 		int flag = 0;
  158. 		for (j = 2; j <= (int)sqrt(i); j++)
  159.                 {
  160. 			if (i % j == 0)
  161.                         {
  162. 				flag++;
  163. 			}
  164. 		}
  165. 		if (flag == 0)
  166.                 {
  167. 			return i;
  168. 		}
  169. 	}
  170. 	return 3;
  171.  
  172. }
  173.  
  174. void main()
  175. {
  176. 	int choice, key, value, n, c;
  177. 	clrscr();
  178.  
  179. 	array = (struct hashtable_item*) malloc(max * sizeof(struct hashtable_item));
  180. 	init_array();
  181.  
  182. 	do {
  183. 		printf("Implementation of Hash Table in C with Double Hashing.\n\n");
  184. 		printf("MENU-: \n1.Inserting item in the Hash Table" 
  185.                               "\n2.Removing item from the Hash Table" 
  186.                               "\n3.Check the size of Hash Table" 
  187.                               "\n4.Display Hash Table"
  188. 		       "\n\n Please enter your choice-:");
  189.  
  190. 		scanf("%d", &choice);
  191.  
  192. 		switch(choice) 
  193.                 {
  194.  
  195. 		case 1:
  196.  
  197. 		      printf("Inserting element in Hash Table\n");
  198. 		      printf("Enter key and value-:\t");
  199. 		      scanf("%d %d", &key, &value);
  200. 		      insert(key, value);
  201.  
  202. 		      break;
  203.  
  204.    		case 2:
  205.  
  206. 		      printf("Deleting in Hash Table \n Enter the key to delete-:");
  207. 		      scanf("%d", &key);
  208. 		      remove_element(key);
  209.  
  210. 		      break;
  211.  
  212. 		case 3:
  213.  
  214. 		      n = size_of_hashtable();
  215. 		      printf("Size of Hash Table is-:%d\n", n);
  216.  
  217. 		      break;
  218.  
  219. 		case 4:
  220.  
  221. 		      display();
  222.  
  223. 		      break;
  224.  
  225. 		default:
  226.  
  227. 		       printf("Wrong Input\n");
  228.  
  229. 		}
  230.  
  231. 		printf("\n Do you want to continue-:(press 1 for yes)\t");
  232. 		scanf("%d", &c);
  233.  
  234. 	}while(c == 1);
  235.  
  236. 	getch();
  237.  
  238. }
Program Explanation

Note : Hash Table with Double Hashing consists of probing through array elements (looping back if necessary) but differs in the way that it calculates other hash code of given key and uses that in probing
hashcode2 = primeNum – (key % primeNum) , where primeNum is largest prime number less that array size
Probing formula after calculating hashcode2 -:
(hashcode1 + (h * hashcode2)) % arraySize , h = 1, 2, 3, 4 and so on.
1. Create a structure, item having a key and value representing data to be inserted in hash table.
2. Create another structure, hashtable_item with variable data (key and value) and flag as a status variable which informs about the status of array index.
flag = 1 : presence of some data at the array index.
flag = 0 : data not present in array index even once
flag = 2 : data had been removed from array index at least once
3. Now create an array of structure (hashtable_item) of some certain size(7, in this case). This array will be our hash table.
Note: array size should be taken a prime number to produce good results.
4. A menu is displayed on the screen.
5. User must choose one option from four choices given in the menu.
6. 1st choice: Inserting item into hash table
(a) Take a key and a value as input.
(b) Calculate index as per the given key (using hashcode() function).
(c) Access the element at this calculated index in array.
(d) If there is no element at that particular array index, add straight way.
(e) If an element is present, check whether the given key matches the element’s key. If yes, then update it’s value and return. Otherwise probe through subsequent elements (looping back if necessary), to find free space. While probing
* if given key matches the element’s key, update its value and return.
* if a free space is found, add the data at that position.
Probing will stop until we reach the same element from where we began probing. Until then, if no free space is found, then add will fail.
7. 2nd choice: Removing a key from hash table
(a) Take a key as input which needs to be removed.
(b) Calculate index as per the given key (using hashcode() function).
(c) Access the element at the calculated array index.
(d) If an element is present, check whether the given key matches the element’s key. If yes, then delete the key and return decrementing the size. Otherwise probe through subsequent elements (looping back if necessary), to find free space with flag = 0. While probing
* if given key matches the element’s key, delete and return.
* if a free space is found (with flag = 2), continue to probe.
(e) If no free space (flag = 0) is found even after probing through all element it means, key does not exist in the hash table.
8. 3rd choice: Size of hash table
(a) Each time we add a new data item into the hash table, we increment it’s size by 1.
(b) Each time we remove a data item from the hash table, we decrement it’s size by 1.
(c) The size of the hash table can be determined either by size variable or size_of_hashtable() method.

advertisement

9. 4th choice: Display hash table
(a) Function display() runs for displaying hash table contents.
(b) Here a for loop runs from 0 to array_size-1 with i as iterator.
(c) The code inside loop consists of taking i as index and accessing each element at that index of array.

Runtime Test Cases
 
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display Hash Table
 
Please enter your choice-: 3
Size of hash table is-: 0
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display Hash Table
 
Please enter your choice-: 1
Inserting element in hash table
Enter key and value-:   12 	1
 
 Key (12) has been inserted
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display Hash Table
 
Please enter your choice-: 1
Inserting element in Hash Table
Enter key and value-:   47 	1
 
 probing
 
 Key (47) has been inserted
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display Hash Table
 
Please enter your choice-: 1
Inserting element in Hash Table
Enter key and value-:   61 	1
 
 probing
 
 Key (61) has been inserted
 
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display Hash Table
 
Please enter your choice-: 3
Size of hash table is-: 3
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display Hash Table
 
Please enter your choice-: 4
 
Array[0] has  no elements
 
Array[1] has elements-:
47 (key) and 1 (value)
 
Array[2] has elements-:
61 (key) and 1 (value)
 
Array[3] has elements-:
 
 
Array[4] has no elements
 
Array[5] has elements-:
12 (key) and 1 (value)
 
Array[6] has no elements
 
 
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display Hash Table
 
Please enter your choice-: 2
Deleting in hash table
Enter the key to delete-: 61
 
 Key (61) has been removed
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C with Double Hashing
MENU-:
1. Inserting item in the Hash Table
2. Removing item from the Hash Table
3. Check the size of Hash Table
4. Display a Hash Table
 
Please enter your choice-: 2
Deleting in hash table
Enter the key to delete-: 61
 
 This key does not exist
 
Do you want to continue-:(press 1 for yes) 2

Sanfoundry Global Education & Learning Series – 1000 C Programs.

advertisement

Here’s the list of Best Reference Books in C Programming, Data Structures and Algorithms.

advertisement
advertisement
advertisement
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He is Linux Kernel Developer & SAN Architect and is passionate about competency developments in these areas. He lives in Bangalore and delivers focused training sessions to IT professionals in Linux Kernel, Linux Debugging, Linux Device Drivers, Linux Networking, Linux Storage, Advanced C Programming, SAN Storage Technologies, SCSI Internals & Storage Protocols such as iSCSI & Fiber Channel. Stay connected with him @ LinkedIn