hashtable.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*************************************/
  2. /* Auteur : Rémi Synave */
  3. /* Date de création : 01/03/07 */
  4. /* Date de modification : 15/03/15 */
  5. /* Version : 0.4 */
  6. /*************************************/
  7. /***************************************************************************/
  8. /* This file is part of a2ri. */
  9. /* */
  10. /* a2ri is free software: you can redistribute it and/or modify it */
  11. /* under the terms of the GNU Lesser General Public License as published */
  12. /* by the Free Software Foundation, either version 3 of the License, or */
  13. /* (at your option) any later version. */
  14. /* */
  15. /* a2ri is distributed in the hope that it will be useful, */
  16. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  17. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  18. /* GNU Lesser General Public License for more details. */
  19. /* */
  20. /* You should have received a copy of the GNU Lesser General Public */
  21. /* License along with a2ri. */
  22. /* If not, see <http://www.gnu.org/licenses/>. */
  23. /***************************************************************************/
  24. #include "hashtable.h"
  25. /********** INTERMEDIATE TYPES AND FUNCTIONS **********/
  26. /* Les fonctions intermédiaires sont préfixées de IF */
  27. /* et les types intermédiaires de IT */
  28. int
  29. IFhash (
  30. char *key)
  31. {
  32. char *p = key;
  33. int h = *p;
  34. if (h)
  35. {
  36. for (p += 1; *p != '\0'; p++)
  37. {
  38. h = (h << 5) - h + *p;
  39. }
  40. }
  41. return h;
  42. }
  43. /********** MAIN FUNCTIONS **********/
  44. /**
  45. Création d'une table de hachage
  46. @param size taille de la table de hachage
  47. @return la nouvelles table de hachage
  48. **/
  49. hashtable *
  50. hashtable_new (
  51. int size)
  52. {
  53. hashtable *table = (hashtable *) malloc (sizeof (hashtable));
  54. a2ri_erreur_critique_si (table == NULL,
  55. "erreur allocation memoire pour table\nhashtable_new");
  56. table->size_array = size;
  57. table->count = 0;
  58. table->list = (container **) malloc (size * sizeof (container *));
  59. a2ri_erreur_critique_si (table->list == NULL,
  60. "erreur allocation memoire pour table->list\nhashtable_new");
  61. for (int i = 0; i < size; i++)
  62. table->list[i] = NULL;
  63. return table;
  64. }
  65. /**
  66. Destruction de la table de hachage avec libération de la mémoire
  67. @param table la table de hachage
  68. @return aucun;
  69. **/
  70. void
  71. hashtable_free (
  72. hashtable * table)
  73. {
  74. container *parc,
  75. *prev;
  76. for (int i = 0; i < table->size_array; i++)
  77. {
  78. parc = table->list[i];
  79. prev = parc;
  80. while (parc != NULL)
  81. {
  82. vf_edge_free (parc->data);
  83. free (parc->data);
  84. prev = parc;
  85. parc = parc->next;
  86. free (prev);
  87. }
  88. }
  89. free (table->list);
  90. }
  91. /**
  92. Ajout d'une arete dans la table de hachage
  93. @param table la table de hachage
  94. @param e l'arete a ajouter
  95. @return aucun
  96. **/
  97. void
  98. hashtable_add (
  99. hashtable * table,
  100. vf_edge * e)
  101. {
  102. char temp[20];
  103. if (e->ve1 < e->ve2)
  104. sprintf (temp, "%d,%d", e->ve1, e->ve2);
  105. else
  106. sprintf (temp, "%d,%d", e->ve2, e->ve1);
  107. int index = abs (IFhash (temp) % table->size_array);
  108. container *parc = table->list[index];
  109. if (parc == NULL)
  110. {
  111. table->list[index] = (container *) malloc (sizeof (container));
  112. a2ri_erreur_critique_si (table->list[index] == NULL,
  113. "erreur allocation memoire pour table->list[index]\nhashtable_add");
  114. parc = table->list[index];
  115. //TODO modifier ici pour garantir le const de l'arete
  116. //creer une nouvelle arete pour parc->data et copier les infos de l'arete e
  117. parc->data = e;
  118. parc->next = NULL;
  119. }
  120. else
  121. {
  122. while (parc->next != NULL)
  123. parc = parc->next;
  124. parc->next = (container *) malloc (sizeof (container));
  125. a2ri_erreur_critique_si (parc->next == NULL,
  126. "erreur allocation memoire pour parc->next\nhashtable_add");
  127. //TODO idem voir ci-dessus
  128. parc = parc->next;
  129. parc->data = e;
  130. parc->next = NULL;
  131. }
  132. table->count = table->count + 1;
  133. }
  134. /**
  135. Recherche d'une arete dans la table de hachage
  136. @param ve1 premier sommet de l'arete
  137. @param ve2 second sommet de l'arete
  138. @return l'arete si elle se trouve dans la table de hachage, NULL sinon.
  139. **/
  140. vf_edge *
  141. hashtable_look_for (
  142. const hashtable * const table,
  143. int ve1,
  144. int ve2)
  145. {
  146. char variable[300];
  147. a2ri_erreur_critique_si (variable == NULL,
  148. "erreur allocation memoire pour temp\nhashtable_look_for\n");
  149. variable[0] = 0;
  150. int trouve = 0;
  151. if (ve1 < ve2)
  152. sprintf (variable, "%d,%d", ve1, ve2);
  153. else
  154. sprintf (variable, "%d,%d", ve2, ve1);
  155. int index = abs (IFhash (variable) % table->size_array);
  156. container *parc = table->list[index];
  157. while (!trouve && parc != NULL)
  158. {
  159. if ((parc->data->ve1 == ve1 && parc->data->ve2 == ve2)
  160. || (parc->data->ve1 == ve2 && parc->data->ve2 == ve1))
  161. trouve = 1;
  162. else
  163. parc = parc->next;
  164. }
  165. if (trouve)
  166. return parc->data;
  167. else
  168. return NULL;
  169. }
  170. /**
  171. Affichage d'une table de hachage
  172. @param table la table de hachage
  173. @return aucun
  174. **/
  175. void
  176. hashtable_display (
  177. const hashtable * const table)
  178. {
  179. printf ("***** TABLE DE HACHAGE *****\n");
  180. for (int i = 0; i < table->size_array; i++)
  181. {
  182. printf ("cle : %d\n", i);
  183. container *parc = table->list[i];
  184. while (parc != NULL)
  185. {
  186. vf_edge_display (parc->data);
  187. parc = parc->next;
  188. }
  189. printf ("\n");
  190. }
  191. printf ("****************************\n");
  192. }
  193. /**
  194. Retourne la taille de la table, le nombre d'éléments
  195. @param table la table de hachage
  196. @return aucun
  197. **/
  198. int
  199. hashtable_size (
  200. const hashtable * const table)
  201. {
  202. return table->count;
  203. }
  204. /**
  205. Applique la fonction passé en paramètre à tous les éléments contenus dans la table
  206. @param table la table de hachage
  207. @param func la fonction à appliquer
  208. @param user_data un pointeur vers des données que l'on veut passé en paramètre à la fonction
  209. @return aucun
  210. **/
  211. void
  212. hashtable_foreach (
  213. hashtable * table,
  214. ptf_foreach func,
  215. void *user_data)
  216. {
  217. for (int i = 0; i < table->size_array; i++)
  218. {
  219. container *parc = table->list[i];
  220. while (parc != NULL)
  221. {
  222. func (i, parc->data, user_data);
  223. parc = parc->next;
  224. }
  225. }
  226. }