C Program to Implement Hash Tables Chaining with Binary Trees

This is a C Program to Implement Hash Tables Chaining with Binary Trees.

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. This program will implement hash table where at each array index, we will create a Binary tree, to prevent key collision. Key having same index will be stored in Binary tree as it can store multiple data.

Problem Solution

1. Create an array of Binary Trees (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 Binary Tree of a particular array index.
4. Using the generated index, extract the Binary Tree located in that array index.
5. In case of absence of a tree, create one and insert a data item (key and value) into it and increment the size of hash table.
6. In case the tree already exists, search for the key (given as input) in the Binary Tree, and add the data item (key and value) into it if key does not belong to the tree and increment the size, otherwise update the value of given (and already present) key in the Binary Tree.
7. To display all the elements of hash table, Binary Tree at each index is extracted and all the elements (key and value) are read and printed.
8. To remove a key from hash table, we will first calculate its index and extract its Binary Tree, find the key in tree 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 Binary Tree. 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<stdlib.h>
  4.  
  5. int max = 10;          /* determines the maximum capacity of Hash Table array */
  6. int size = 0;          /* determines the number of elements present in Hash Table */
  7.  
  8. /* node for storing an item in a Binary Tree */
  9. struct node 
  10. {
  11. 	int key;
  12. 	int value;
  13. 	struct node *left;
  14. 	struct node *right;
  15. };
  16.  
  17. /* for storing a Binary Tree at each index of Hash Table array */
  18. struct bst 
  19. {
  20. 	struct node *head;
  21. 	/* head pointing to the root of Binary Tree */
  22. };
  23.  
  24. struct bst *array;
  25.  
  26. void insert_element(struct node *tree, struct node *item);
  27. struct node* find(struct node *tree, int key);
  28. struct node* remove_element(struct node *tree, int key);
  29. void display_tree(struct node *tree);
  30.  
  31. /* this function creates an index corresponding to the every given key */
  32. int hashcode(int key)
  33. {
  34. 	return (key % max);
  35. }
  36.  
  37. void add(int key, int value)
  38. {
  39. 	int index = hashcode(key);
  40.  
  41. 	/* extracting Binary Tree at the given index */
  42. 	struct node *tree = (struct node*) array[index].head;
  43.  
  44. 	/* creating an item to insert in the hashtable */
  45. 	struct node *new_item = (struct node*) malloc(sizeof(struct node));
  46. 	new_item->key = key;
  47. 	new_item->value = value;
  48. 	new_item->left = NULL;
  49. 	new_item->right = NULL;
  50.  
  51. 	if (tree == NULL) 
  52.         {
  53. 		/* absence of Binary Tree at a given index of Hash Table array */
  54.  
  55. 		printf("Inserting %d(key) and %d(value)\n", key, value);
  56. 		array[index].head = new_item;
  57. 		size++;
  58.  
  59. 	}
  60. 	else {
  61. 		/* a Binary Tree is present at given index of Hash Table */
  62.  
  63. 		struct node *temp = find(tree, key);
  64. 		if (temp == NULL) 
  65.                 {
  66. 			/*
  67. 			 * Key not found in existing Binary Tree
  68. 			 * Adding the key in existing Binary Tree
  69. 			*/
  70.  
  71. 			printf("Inserting %d(key) and %d(value) \n", key, value);
  72. 			insert_element(tree, new_item);
  73. 			size++;
  74.  
  75. 		}
  76. 		else 
  77.                 {
  78. 			/*
  79. 			 * Key already present in existing Binary Tree
  80. 			 * Updating the value of already existing key
  81. 			*/
  82.  
  83. 			temp->value = value;
  84.  
  85. 		}
  86. 	}
  87.  
  88. }
  89.  
  90.  
  91. /*
  92.  * this function finds the given key in the Binary Tree
  93.  * returns the node containing the key
  94.  * returns NULL in case key is not present
  95. */
  96. struct node* find(struct node *tree, int key)
  97. {
  98. 	if (tree == NULL) 
  99.         {
  100. 		return NULL;
  101. 	}
  102. 	if (tree->key == key)
  103.         {
  104. 		return tree;
  105. 	}
  106. 	else if (key < tree->key)
  107.         {
  108. 		return find(tree->left, key);
  109. 	}
  110. 	else 
  111.         {
  112. 		return find(tree->right, key);
  113. 	}
  114.  
  115. }
  116.  
  117. /* this function inserts the newly created node in the existing Binary Tree */
  118. void insert_element(struct node *tree, struct node *item)
  119. {
  120. 	if (item->key < tree->key)
  121.         {
  122. 		if (tree->left == NULL)
  123.                 {
  124. 			tree->left = item;
  125. 			return;
  126. 		}
  127. 		else 
  128.                 {
  129. 			insert_element(tree->left, item);
  130. 			return;
  131. 		}
  132. 	}
  133. 	else if (item->key > tree->key)
  134.         {
  135. 		if (tree->right == NULL)
  136.                 {
  137. 			tree->right = item;
  138. 			return;
  139. 		}
  140. 		else
  141.                 {
  142. 			insert_element(tree->right, item);
  143. 			return;
  144. 		}
  145. 	}
  146. }
  147.  
  148. /* displays the content of hash table */
  149. void display()
  150. {
  151. 	int i = 0;
  152. 	for(i = 0; i < max; i++) 
  153.         {
  154. 		struct node *tree = array[i].head;
  155. 		if (tree == NULL)
  156.                 {
  157. 			printf("\n array[%d] has no elements \n", i);
  158. 		}
  159. 		else
  160.                 {
  161. 			printf("\n array[%d] has elements \t", i);
  162. 			display_tree(tree);
  163. 		}
  164. 	}
  165. }
  166.  
  167. /* displays content of binary tree of particular index */
  168. void display_tree(struct node *tree)
  169. {
  170.     	if (tree == NULL)
  171.         {
  172.         	return;
  173.     	}
  174.     	printf("%d and %d \t", tree->key, tree->value);
  175.  
  176.     	if (tree->left != NULL)
  177.         {
  178.         	display_tree(tree->left);
  179.     	}
  180.     	if (tree->right != NULL)
  181.         {
  182.         	display_tree(tree->right);
  183.     	}
  184.  
  185. }
  186.  
  187. /* for initializing the hash table */
  188. void init()
  189. {
  190.     	int i = 0;
  191.     	for(i = 0; i < max; i++)
  192.         {
  193.         	array[i].head = NULL;
  194.     	}
  195.  
  196. }
  197.  
  198. /* returns the size of hash table */
  199. int size_of_hashtable()
  200. {
  201. 	return size;
  202. }
  203.  
  204. /* to delete a key from hash table */
  205. void delete(int key) 
  206. {
  207.     	int index = hashcode(key);
  208.     	struct node *tree = (struct node*)array[index].head;
  209.     	if (tree == NULL)
  210.         {
  211.         	printf("\n %d Key not present \n", key);
  212.     	}
  213.     	else 
  214.         {
  215.         	struct node *temp = find(tree, key);
  216.         	if (temp == NULL) 
  217.                 {
  218.             		printf("%d Key not present.", key);
  219.         	}
  220.         	else 
  221.                 {
  222.             		tree = remove_element(tree, key);
  223. 			printf("%d has been removed form the hash table\n", key);
  224.         	}
  225.     	}
  226. }
  227.  
  228. struct node* remove_element(struct node *tree, int key)
  229. {
  230.     if (tree == NULL)
  231.     {
  232.         	return NULL;
  233.     }
  234.     if (key < tree->key) 
  235.     {
  236.         	tree->left = remove_element(tree->left, key);
  237.         	return tree;
  238.     }
  239.     else if (key > tree->key) 
  240.     {
  241.         	tree->right = remove_element(tree->right, key);
  242.         	return tree;
  243.     }
  244.     else {
  245. 		/* reached the node */
  246.         	if (tree->left == NULL  &&  tree->right == NULL) 
  247.                 {
  248.             		size--;
  249.             		return tree->left;
  250.         	}
  251. 		else if (tree->left != NULL  &&  tree->right == NULL) 
  252.                 {
  253.             		size--;
  254.             		return tree->left;
  255.         	}
  256. 		else if (tree->left == NULL  &&  tree->right != NULL) 
  257.                 {
  258.             		size--;
  259.                         return tree->right;
  260.         	}
  261. 		else {
  262.             		struct node *left_one = tree->left;
  263.  
  264.             		while (left_one->right != NULL) 
  265.                         {
  266.                 		left_one = left_one->right;
  267.             		}
  268.  
  269.  		        tree->key = left_one->key;
  270.                		tree->value = left_one->value;
  271.              		tree->left = remove_element(tree->left, tree->key);
  272.             		return tree;
  273.          	}
  274.     }
  275. }
  276.  
  277. void main()
  278. {
  279.     	int choice, key, value, n, c;
  280. 	clrscr();
  281.  
  282. 	array = (struct bst*)malloc(max * sizeof(struct bst*));
  283. 	init();
  284.  
  285. 	do {
  286. 		printf("Implementation of Hash Table in C chaining with Binary Trees\n\n");
  287. 		printf("MENU-: \n1.Insert an item in the Hash Table" 
  288.                               "\n2.Remove an item from the Hash Table" 
  289.                               "\n3.Check the size of Hash Table" 
  290.                               "\n4.Display Hash Table"
  291. 		       "\n\n Please enter your choice-:");
  292.  
  293.  		scanf("%d", &choice);
  294.  
  295. 		switch(choice) 
  296.                 {
  297.  
  298. 		case 1:
  299.  
  300. 		      printf("Inserting element in Hash Table\n");
  301. 		      printf("Enter key and value-:\t");
  302. 		      scanf("%d %d", &key, &value);
  303. 		      add(key, value);
  304.  
  305. 		      break;
  306.  
  307. 		case 2:
  308.  
  309. 		      printf("Deleting item from Hash Table \n Enter the key to delete-:");
  310. 		      scanf("%d", &key);
  311. 		      delete(key);
  312.  
  313. 		      break;
  314.  
  315. 		case 3:
  316.  
  317. 		      n = size_of_hashtable();
  318. 		      printf("Size of Hash Table is-:%d\n", n);
  319.  
  320. 		      break;
  321.  
  322. 		case 4:
  323.  
  324. 		      display();
  325.  
  326. 		      break;
  327.  
  328. 		default:
  329.  
  330. 		       printf("Wrong Input\n");
  331.  
  332. 		}
  333.  
  334. 		printf("\n Do you want to continue-: (press 1 for yes) \t");
  335. 		scanf("%d", &c);
  336.  
  337. 	}while(c == 1);
  338.  
  339. 	getch();
  340.  
  341.  
  342. }
Program Explanation

1. Create a structure node(binary tree item) with key and value as data and left and right as a pointer variable which points the structure element of node type (left pointing to the left child of current node and right pointing to the right child of current node).
2. Create another structure(for binary tree) with head having the address of root element of binary tree.
3. Now create an array of binary tree 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 binary tree at the calculated array index.
(d) If binary tree is present, check whether the key already present in it by finding the node containing key using find() method which returns NULL if key is not present. In that case, we will create a data item and add it into binary tree. If key is already present in the tree, we will update the value of node containing key.
(e) If there is no tree at that particular array index, which means the key is not present in hash table, then create a data item and a binary tree and add the data item to it using insert_element() function.
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 binary tree at the calculated array index.
(d) If tree is present, find the node containing the key in binary tree using find() method which returns NULL if key not present. The key is removed using delete() method if it is present otherwise ‘Key not present’ message will get displayed.
(e) If there is no binary tree 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 binary tree at that index of array.
(d) As the content of each node of tree is displayed the variables left and right (pointers) is used to proceed further until all elements are displayed.

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
Inserting 1(key) and 10(value)
 
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 elements-:		1  10
array[1] has no elements
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
Element 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-: 1
1 has been removed from the Hash Table.
 
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.

If you find any mistake above, kindly email to [email protected]

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.