C Program to Implement Hash Tables Chaining with Doubly Linked Lists

This is a C Program to Implement Hash Tables Chaining with Doubly Linked Lists.

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. Implementing hash table using Doubly Linked List is similar to implementing hash table using Singly Linked List. The difference is that every node of Linked List has address of both, the next and the previous node. This will help removing data from this Linked List faster than Singly Linked List.

Problem Solution

1. Create an array of Doubly Linked List (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 Linked List of a particular array index.
4. Using the generated index, extract the Linked List located in that array index.
5. In case of absence of a list, create one and insert a data item (key and value) into it and increment the size of hash table.
6. In case the list already exists, search for the key (given as input) in the list, and add the data item (key and value) at the end of list if key does not belong to the list and increment the size, otherwise update the value of given (and already present) key in the Linked List.
7. To display all the elements of hash table, Linked List at each index is extracted and elements (key and value) are read until we reach at its end.
8. To remove a key from hash table, we will first calculate its index and extract its Linked List, find the key in list and remove it if it is present.
9. Exit

Program/Source Code

Here is the source code of the C Program to implement a Hash table chaining with Doubly Linked List. The program is successfully compiled and tested using Turbo C compiler in windows environment. The program output is also shown below.

  1.  
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4.  
  5. /* Node for storing an item in a Doubly Linked List */
  6. struct node 
  7. {
  8. 	int key;
  9. 	int value;
  10. 	struct node *next;
  11. 	struct node *prev;
  12. };
  13.  
  14. /* For storing a Linked List at each index of Hash table */
  15. struct arrayitem 
  16. {
  17.  
  18. 	struct node *head;
  19. 	/* head pointing the first element of Linked List at an index of Hash table */
  20.  
  21. 	struct node *tail;
  22. 	/* tail pointing the last element of Linked List at an index of Hash table */
  23.  
  24. };
  25.  
  26. struct arrayitem *array;
  27. int size = 0;         /* Determines the no. of elements present in Hash table */
  28. int max = 10;	      /* Determines the maximum capacity of Hash table array */
  29.  
  30. /* This function creates an index corresponding to the every given key */
  31. int hashcode(int key)
  32. {
  33. 	return (key % max);
  34. }
  35.  
  36. struct node* get_element(struct node *list, int find_index);
  37. void remove_element(int key);
  38. void rehash();
  39. void init_array();
  40.  
  41. void insert(int key, int value)
  42. {
  43. 	float n = 0.0;
  44. 	/*  n => Load Factor, keeps check on whether rehashing is required or not */
  45.  
  46. 	int index = hashcode(key);
  47.  
  48. 	/* Extracting Linked List at a given index */
  49. 	struct node *list = (struct node*) array[index].head;
  50.  
  51. 	/* Creating an item to insert in the hash table */
  52. 	struct node *item = (struct node*) malloc(sizeof(struct node));
  53. 	item->key = key;
  54. 	item->value = value;
  55. 	item->next = NULL;
  56. 	item->prev = NULL;
  57.  
  58. 	if (list == NULL) 
  59.         {
  60. 		/* Absence of Linked List at a given index of Hash table */
  61.  
  62. 		printf("\n  %d (key) and %d (value) has been inserted  \n", key, value);
  63. 		array[index].head = item;
  64. 		array[index].tail = item;
  65. 		size++;
  66.  
  67. 	}
  68.         else
  69.         {
  70. 		/* A Linked List is present at given index of Hash table */
  71.  
  72. 		int find_index = find(list, key);
  73. 		if (find_index == -1) 
  74.                 {
  75. 		 	/*
  76. 			 *Key not found in existing Linked List
  77. 			 *Adding the key at the end of the Linked List
  78. 			*/
  79. 			item->prev = array[index].tail;
  80. 			array[index].tail->next = item;
  81. 			array[index].tail = item;
  82. 			size++;
  83. 			printf("\n %d (key) and %d (value) has been inserted \n", key, value);
  84.  
  85.  
  86. 		}else {
  87. 			/*
  88. 			 *Key already present in Linked List
  89. 			 *Updating the value of already existing key
  90. 			*/
  91.  
  92. 			struct node *element = get_element(list, find_index);
  93. 			element->value = value;
  94.  
  95. 		       }
  96.  
  97. 	}
  98.  
  99. 	/* Calculating Load factor */
  100. 	n = (1.0 * size) / max;
  101. 	if (n >= 0.75) 
  102.         {
  103. 		/* rehashing */
  104.  
  105. 		printf("going to rehash\n");
  106. 		rehash();
  107.  
  108. 	}
  109.  
  110. }
  111.  
  112. void rehash()
  113. {
  114. 	struct arrayitem *temp = array;
  115. 	/* temp pointing to the current Hash table array */
  116.  
  117. 	int i = 0, n=max;
  118. 	size = 0;
  119. 	max = 2 * max;
  120.  
  121. 	/*
  122. 	 *array variable is assigned with newly created Hash table
  123. 	 *with double of previous array size
  124. 	*/
  125. 	array = (struct arrayitem*) malloc(size * sizeof(struct node));
  126. 	init_array();
  127.  
  128. 	for (i = 0; i < n; i++) 
  129.         {
  130.  
  131. 		/* Extracting the Linked List at position i of Hash table array
  132. 		struct node* list = (struct node*) temp[i].head;
  133.  
  134. 		if (list == NULL)
  135.                 {
  136.  
  137. 			/* if there is no Linked List, then continue */
  138. 			continue;
  139.  
  140. 		}
  141. 		else 
  142.                 {
  143. 			/*
  144. 			 *Presence of Linked List at i
  145. 			 *Keep moving and accessing the Linked List item until the end.
  146. 			 *Get one key and value at a time and add it to new Hash table array.
  147. 			*/
  148.  
  149. 			while (list != NULL)
  150.                         {
  151. 				insert(list->key, list->value);
  152. 				list = list->next;
  153. 			}
  154.  
  155. 		}
  156.  
  157. 	}
  158. 	temp = NULL;
  159. }
  160.  
  161. /*
  162.  *This function finds the given key in the Linked List
  163.  *Returns it's index
  164.  *Returns -1 in case key is not present
  165. */
  166. int find(struct node *list, int key)
  167. {
  168. 	int retval = 0;
  169. 	struct node *temp = list;
  170. 	while (temp != NULL)
  171.         {
  172. 		if (temp->key == key)
  173.                 {
  174. 			return retval;
  175. 		}
  176. 		temp = temp->next;
  177. 		retval++;
  178. 	}
  179. 	return -1;
  180.  
  181. }
  182.  
  183. /* Returns the node (Linked list item) located at given find_index */
  184. struct node* get_element(struct node *list, int find_index)
  185. {
  186. 	int i = 0;
  187. 	struct node *temp = list;
  188. 	while (i != find_index)
  189.         {
  190. 		temp = temp->next;
  191. 		i++;
  192. 	}
  193. 	return temp;
  194. }
  195.  
  196. /* To remove an element from Hash table */
  197. void remove_element(int key)
  198. {
  199. 	int index = hashcode(key);
  200. 	struct node *list = (struct node*) array[index].head;
  201.  
  202. 	if (list == NULL)
  203.         {
  204. 		printf("\n This key does not exists \n");
  205.  
  206. 	}
  207. 	else
  208.         {
  209. 		int find_index = find(list, key);
  210.  
  211. 		if (find_index == -1)
  212.                 {
  213. 			printf("\n This key does not exists \n");
  214.  
  215. 		}
  216. 		else 
  217.                 {
  218. 			struct node *temp = list;
  219. 			if (temp->key == key)
  220.                         {
  221.  
  222. 				array[index].head = temp->next;
  223. 				array[index].head->prev = NULL;
  224. 				size--;
  225. 				printf("\n This key has been removed \n");
  226. 				return;
  227. 			}
  228.  
  229. 			while (temp->key != key)
  230.                         {
  231. 				  temp = temp->next;
  232. 			}
  233.  
  234. 			if (array[index].tail == temp)
  235.                         {
  236. 				temp->prev->next = NULL;
  237. 				array[index].tail = temp->prev;
  238. 				size--;
  239.  
  240. 			}
  241.                         else 
  242.                         {
  243. 				temp->prev->next = temp->next;
  244. 				temp->next->prev = temp->prev;
  245. 				size--;
  246.  
  247. 			}
  248.  
  249. 			printf("This key has been removed\n");
  250.  
  251. 		}
  252.  
  253. 	}
  254.  
  255. }
  256.  
  257. /* To display the contents of Hash table */
  258. void display()
  259. {
  260. 	int i = 0;
  261. 	for (i = 0; i < max; i++)
  262.         {
  263. 		struct node *temp = array[i].head;
  264. 		if (temp == NULL)
  265.                 {
  266. 			printf("array[%d] has no elements \n", i);
  267.  
  268. 		}
  269. 		else 
  270.                 {
  271. 			printf("array[%d] has elements-: ", i);
  272. 			while (temp != NULL) 
  273.                         {
  274. 				printf("key= %d  value= %d\t", temp->key, temp->value);
  275. 				temp = temp->next;
  276. 			}
  277. 			printf("\n");
  278.  
  279. 		}
  280. 	}
  281. }
  282.  
  283. /* For initializing the Hash table */
  284. void init_array()
  285. {
  286. 	int i;
  287. 	for (i = 0; i < max; i++)
  288.         {
  289. 		array[i].head = NULL;
  290. 		array[i].tail = NULL;
  291. 	}
  292.  
  293. }
  294.  
  295. /* Returns size of Hash table */
  296. int size_of_array()
  297. {
  298. 	return size;
  299. }
  300.  
  301. void main()
  302. {
  303. 	int choice, key, value, n, c;
  304. 	clrscr();
  305.  
  306. 	array = (struct arrayitem*) malloc(max * sizeof(struct arrayitem*));
  307. 	init_array();
  308.  
  309. 	do {
  310. 		printf("Implementation of Hash Table in C chaining with Doubly Linked List \n\n");
  311. 		printf("MENU-: \n1.Inserting item in the Hash Table"
  312.                               "\n2.Removing item from the Hash Table" 
  313.                               "\n3.Check the size of Hash Table" 
  314.                               "\n4.Display a Hash Table"
  315. 		       "\n\n Please enter your choice-:");
  316.  
  317. 		scanf("%d", &choice);
  318.  
  319. 		switch(choice) 
  320.                 {
  321.  
  322. 		case 1:
  323.  
  324. 		      printf("Inserting element in Hash Table\n");
  325. 		      printf("Enter key and value-:\t");
  326. 		      scanf("%d %d", &key, &value);
  327. 		      insert(key, value);
  328.  
  329. 		      break;
  330.  
  331. 		case 2:
  332.  
  333. 		      printf("Deleting in Hash Table \n Enter the key to delete-:");
  334. 		      scanf("%d", &key);
  335. 		      remove_element(key);
  336.  
  337. 		      break;
  338.  
  339. 		case 3:
  340.  
  341. 		      n = size_of_array();
  342. 		      printf("Size of Hash Table is-: %d\n", n);
  343.  
  344. 		      break;
  345.  
  346. 		case 4:
  347.  
  348. 		      display();
  349.  
  350. 		      break;
  351.  
  352. 		default:
  353.  
  354. 		       printf("Wrong Input\n");
  355.  
  356. 		}
  357.  
  358. 		printf("\n Do you want to continue-:(press 1 for yes)\t");
  359. 		scanf("%d", &c);
  360.  
  361. 	}while(c == 1);
  362.  
  363. 	getch();
  364.  
  365. }
Program Explanation

1. Create a structure node (Doubly Linked List item) with key and value as data and next as a pointer variable which points the structure element of node type.
2. Create another structure (for Doubly Linked List) with head having the address of first element of Linked List and tail having the address of last element of Linked List.
3. Now create an array of Doubly Linked List of some certain size (10, in this case).
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.
(c) Locate the linked list at the calculated array index.
(d) If Linked List is present, check whether the key already present in it by finding the location of key using find() method which returns -1 if key is not present. In that case, we will create a data item and add it to the end of Linked List. If key is already present in the list, we will get its location index and extract the element using get_element() function and update its value.
(e) If there is no Linked List at that particular array index, which means the key is not present in hash table, then create a data item and a Linked List and add the data item to it.
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.
(c) Locate the Linked List at the calculated array index.
(d) If Linked List is present, find the location index of the key in Linked List using find() method which returns -1 if key not present. The key is removed using remove() method if it is present otherwise ‘Key not present’ message will get displayed.
(e) If there is no Linked List at that particular array index, which means the key is not present in hash table, therefore no deletion is required.
8. 3rd choice: Size of hash table
(a) Each time we add a new data item into the hash table, we increment its size by 1.
(b) The size of the hash table can be determined either by size variable or size_of_hashtable() method.

advertisement
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 locating each linked list at that index of array.
(d) As the content of each node of Linked List is displayed the next variable (pointer) is used to proceed further until the end of list is reached.

Runtime Test Cases
 
Implementation of Hash Table in C chaining with Binary Tree.
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 chaining with Binary Tree.
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-:   1 	10
 
 1(key) and 10(value) has been inserted
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C chaining with Binary Tree.
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-:   101 	1
 
 101(key) and 1(value) has been inserted
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C chaining with Binary Tree.
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-:   51 	2
 
 51(key) and 2(value) has been inserted
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C chaining with Binary Tree.
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 no elements	key=1  value=10		key=101  value=1	key=51  value=2
array[2] has no elements
array[3] has no elements
array[4] has no elements
array[5] has no elements
array[6] has no elements
array[7] has no elements
array[8] has no elements
array[9] has no elements
*****************************
 
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C chaining with Binary Tree.
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 key from Hash Table
Enter the key to delete-: 3
 
 This key does not exists.
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C chaining with Binary Tree.
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 key from Hash Table
Enter the key to delete-: 101
 
 This Key has been deleted.
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C chaining with Binary Tree.
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 no elements	key=1  value=10		key=51  value=2
array[2] has no elements
array[3] has no elements
array[4] has no elements
array[5] has no elements
array[6] has no elements
array[7] has no elements
array[8] has no elements
array[9] has no elements
 
 
Do you want to continue-:(press 1 for yes) 1
Implementation of Hash Table in C chaining with Binary Tree.
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-: 2
 
Do you want to continue-:(press 1 for yes) 2

Sanfoundry Global Education & Learning Series – 1000 C Programs.

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

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.