Advertisement
Guest User

Untitled

a guest
Dec 6th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. #include "hashtable.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. //#pragma once
  5. //#ifndef HASH_TABLE_H_INCLUDED
  6. //#define HASH_TABLE_H_INCLUDED
  7.  
  8. typedef struct element
  9. {
  10. int key;
  11. int data;
  12. struct element* next;
  13. } list;
  14.  
  15. typedef struct
  16. {
  17. int max_lenght;
  18. int size;
  19. int amount_blocks;
  20. list** table;
  21. } hash_table;
  22.  
  23. int control_lenght;
  24. int index_max_lenght;
  25.  
  26. int get_hash(int a, int m)
  27. {
  28. return (a % m);
  29. }
  30.  
  31. list* get_last(list* head)
  32. {
  33. while (head->next)
  34. head = head->next;
  35. return head;
  36. }
  37.  
  38. void add(hash_table* head, int k, int x)
  39. {
  40. if (*head == NULL)
  41. {
  42. *head = (list*)malloc(sizeof(list));
  43. (*head)->key = k;
  44. (*head)->data = x;
  45. (*head)->next = NULL;
  46. }
  47. else
  48. {
  49. list* last = get_last(*head);
  50. list* new_last = (list*)malloc(sizeof(list));
  51. new_last->key = k;
  52. new_last->data = x;
  53. new_last->next = NULL;
  54. last->next = new_last;
  55. }
  56. }
  57.  
  58. void print(list* head)
  59. {
  60. while (head)
  61. {
  62. printf("key %d : value %d\n", head->key, head->data);
  63. head = head->next;
  64. }
  65. printf("\n");
  66. }
  67.  
  68. void print_table(hash_table* hash)
  69. {
  70. int i;
  71. for (i = 0; i < size_block * amount_blocks; i++)
  72. {
  73. printf("%d block\n", i);
  74. print(hash[i]);
  75. }
  76. }
  77.  
  78. void free_memory(list* head)
  79. {
  80. while (head)
  81. {
  82. list* next = head->next;
  83. free(head);
  84. head = next;
  85. }
  86. }
  87.  
  88. int find(list* head, int k)
  89. {
  90. while (head)
  91. {
  92. if (head->key == k)
  93. return (head->data);
  94. head = head->next;
  95. }
  96. return -1;
  97. }
  98.  
  99.  
  100. int delete_by_key(hash_table* head, int k)
  101. {
  102. if (*head)
  103. {
  104. if ((*head)->key == k)
  105. {
  106. list* curr = *head;
  107. *head = (*head)->next;
  108. free(curr);
  109. return 1;
  110. }
  111. list* prev = (*head);
  112. list* curr = (*head)->next;
  113. while (curr)
  114. {
  115. if (curr->key == k)
  116. {
  117. prev->next = curr->next;
  118. free(curr);
  119. return 1;
  120. }
  121. prev = curr;
  122. curr = curr->next;
  123. }
  124. }
  125. return 0;
  126. }
  127.  
  128. hash_table* rebalance()
  129. {
  130. int i;
  131. // printf("\nrebalance\n"); // убрать
  132. amount_blocks++;
  133. int m = size_block * amount_blocks;
  134. hash_table* new_hash = (hash_table*)malloc(sizeof(list) * m);
  135. for (i = 0; i < m; i++)
  136. new_hash[i] = NULL;
  137. free(lenght);
  138. lenght = (int*)calloc(m, sizeof(int));
  139. control_lenght = 0;
  140. index_max_lenght = 0;
  141. for (i = 0; i < m - size_block; i++)
  142. {
  143. list* head = hash[i];
  144. while (head)
  145. {
  146. int k = head->key;
  147. int hash_k = get_hash(k, size_block);
  148. int d = head->data;
  149. int curr_box = rand() % amount_blocks;
  150. add(&new_hash[hash_k + size_block * curr_box], k, d);
  151. lenght[hash_k + size_block * curr_box]++;
  152. if (lenght[hash_k + size_block * curr_box] > control_lenght)
  153. {
  154. control_lenght = lenght[hash_k + size_block * curr_box];
  155. index_max_lenght = hash_k + size_block * curr_box;
  156. }
  157. head = head->next;
  158. }
  159. }
  160. for (i = 0; i < m - size_block; i++)
  161. free_memory(hash[i]);
  162. free(hash);
  163.  
  164. // printf("\nend rebalance\n"); // убрать
  165. // print_table(new_hash); // убрать
  166. // printf("\nend rebalance\n"); // убрать
  167. return new_hash;
  168. }
  169.  
  170. void find_and_delete(hash_table* hash, int key)
  171. {
  172. int k = get_hash(key, size_block);
  173. int i;
  174. for (i = 0; i < amount_blocks; i++)
  175. {
  176. if (delete_by_key(&hash[size_block * i + k], key))
  177. {
  178. lenght[size_block * i + k]--;
  179. if (size_block * i + k == index_max_lenght)
  180. control_lenght--;
  181. }
  182. }
  183. }
  184.  
  185. hash_table* insert(hash_table* hash, int key, int x)
  186. {
  187. // print_table(hash); // убрать
  188. int k = get_hash(key, size_block);
  189. // printf("in block %d insert key = %d value = %d\n<<<<<<<>>>>>>>>>>>\n",k,key,x); //убрать
  190.  
  191. int curr_box = rand() % amount_blocks;
  192. find_and_delete(hash, key); //я не понимаю этот вызов здесь к или кеу?, с кеу работает random_number_padding
  193. add(&hash[k + size_block * curr_box], key, x);
  194. lenght[k + size_block * curr_box]++;
  195. if (lenght[k + size_block * curr_box] > control_lenght)
  196. {
  197. control_lenght = lenght[k + size_block * curr_box];
  198. index_max_lenght = k + size_block * curr_box;
  199. }
  200. if (control_lenght > size_block)
  201. {
  202.  
  203. hash = rebalance();
  204.  
  205. }
  206. return hash;
  207. }
  208.  
  209. hash_table* init()
  210. {
  211. hash = (hash_table*)malloc(sizeof(hash_table));
  212. hash -> size = 5;
  213. hash -> max_lenght = 0;
  214. hash -> amount_blocks = 1;
  215. hash -> table = (list**)malloc(sizeof(list*) * (hash -> size) * (hash -> amount_blocks));
  216. //int i;
  217. for (int i = 0; i < (hash -> size) * (hash -> amount_blocks); i++)
  218. {
  219. hash -> table[i] = NULL;
  220. }
  221. return hash;
  222. }
  223.  
  224. int search(int input_key)
  225. {
  226. int k = get_hash(input_key, size_block);
  227. int i;
  228. for (i = 1; i < amount_blocks + 1; i++)
  229. {
  230. return find(hash[k * i], input_key);
  231. }
  232. }
  233.  
  234. void free_table(hash_table* hash)
  235. {
  236. int i;
  237. for (i = 0; i < size_block * amount_blocks; i++)
  238. free_memory(hash[i]);
  239. free(hash);
  240. }
  241.  
  242.  
  243. //#endif // HASH_TABLE_H_INCLUDED
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement