vector.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /*!
  2. Temelia - Vector implementation source file.
  3. Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).
  4. @author Dascalu Laurentiu
  5. This program is free software; you can redistribute it and
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 3
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #include "include/vector.h"
  18. #include "include/common.h"
  19. #include <string.h>
  20. struct _vector_t
  21. {
  22. /*! vector's capacity, maximum keys number */
  23. int capacity;
  24. /*! vector's keys number */
  25. int size;
  26. /*! vector's capacity increment, when it becomes full */
  27. int capacity_increment;
  28. /*! array of references stored in vector */
  29. void **data;
  30. };
  31. // (!) The methods implemented here are trivial, so they're not well commented.
  32. // Private functions. Because those methods are private,
  33. // no assertion is done in their definition.
  34. /* Randomized Quick Sort algorithm is used for sorting the vector. */
  35. static void _quick_sort(void **data, int p, int r, int(*compare)(void *x,
  36. void *y, void *context), void *context);
  37. static int _partition(void **data, int p, int r, int(*compare)(void *x,
  38. void *y, void *context), void *context);
  39. vector_t vector_new(int capacity)
  40. {
  41. vector_t vector;
  42. int i;
  43. _ASSERT(capacity, <=, 0, INVALID_INPUT, NULL);
  44. vector = (struct _vector_t *) _new(sizeof(struct _vector_t));
  45. /*
  46. * Check if the memory allocation fail; if so then
  47. * recover from this failure.
  48. */
  49. _ASSERT(vector, ==, NULL, MEMORY_ALLOCATION, NULL);
  50. vector->size = 0;
  51. vector->capacity = capacity;
  52. vector->capacity_increment = capacity;
  53. vector->data = (void **) _new(capacity * sizeof(void *));
  54. if (vector->data == NULL)
  55. {
  56. temelia_errno = MEMORY_ALLOCATION;
  57. _delete(vector);
  58. return NULL;
  59. }
  60. for (i = 0; i < capacity; i++)
  61. vector->data[i] = NULL;
  62. return vector;
  63. }
  64. vector_t vector_clone(vector_t vector,
  65. void *(*clone)(void *key, void *context), void *context)
  66. {
  67. vector_t cloned_vector;
  68. int i;
  69. _ASSERT(vector, ==, NULL, NULL_POINTER, NULL);
  70. cloned_vector = vector_new(vector->capacity);
  71. if (clone != NULL)
  72. {
  73. for (i = 0; i < vector->size; i++)
  74. cloned_vector->data[i] = clone(vector->data[i], context);
  75. }
  76. else
  77. {
  78. for (i = 0; i < vector->size; i++)
  79. cloned_vector->data[i] = vector->data[i], context;
  80. }
  81. cloned_vector->size = vector->size;
  82. return cloned_vector;
  83. }
  84. void vector_delete(vector_t vector)
  85. {
  86. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  87. vector->size = vector->capacity = vector->capacity_increment = 0;
  88. _delete(vector->data);
  89. _delete(vector);
  90. }
  91. void vector_clear(vector_t vector)
  92. {
  93. int i;
  94. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  95. for (i = 0; i < vector->size; i++)
  96. vector->data[i] = NULL;
  97. vector->size = 0;
  98. }
  99. int vector_get_capacity(vector_t vector)
  100. {
  101. _ASSERT(vector, ==, NULL, NULL_POINTER, -1);
  102. return vector->capacity;
  103. }
  104. int vector_get_size(vector_t vector)
  105. {
  106. _ASSERT(vector, ==, NULL, NULL_POINTER, -1);
  107. return vector->size;
  108. }
  109. int vector_get_capacity_increment(vector_t vector)
  110. {
  111. _ASSERT(vector, ==, NULL, NULL_POINTER, 0);
  112. return vector->capacity_increment;
  113. }
  114. void *vector_get_internal_representation(vector_t vector)
  115. {
  116. _ASSERT(vector, ==, NULL, NULL_POINTER, 0);
  117. return vector->data;
  118. }
  119. void vector_set_size(vector_t vector, int new_size)
  120. {
  121. int i;
  122. // Should not receive a null pointer, a negative new keys number or
  123. // a bigger new keys then current vector's capacity.
  124. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  125. _ASSERT(new_size, <, 0, INVALID_INPUT,);
  126. _ASSERT(new_size, >, vector->capacity, INVALID_INPUT,);
  127. if (new_size < vector->size)
  128. {
  129. for (i = new_size; i < vector->size; i++)
  130. vector->data[i] = NULL;
  131. }
  132. else if (new_size < vector->capacity)
  133. {
  134. for (i = vector->size; i < new_size; i++)
  135. vector->data[i] = NULL;
  136. }
  137. vector->size = new_size;
  138. }
  139. void vector_set_capacity_increment(vector_t vector, int new_capacity_increment)
  140. {
  141. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  142. _ASSERT(new_capacity_increment, <, 0, NULL_POINTER,);
  143. vector->capacity_increment = new_capacity_increment;
  144. }
  145. void vector_set_key_at(vector_t vector, int position, void *key)
  146. {
  147. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  148. _ASSERT(position, <, 0, INVALID_INPUT,);
  149. _ASSERT(position, >=, vector->size, INVALID_INPUT,);
  150. vector->data[position] = key;
  151. }
  152. void *vector_get_key_at(vector_t vector, int position)
  153. {
  154. _ASSERT(vector, ==, NULL, INVALID_INPUT, NULL);
  155. _ASSERT(position, <, 0, INVALID_INPUT, NULL);
  156. _ASSERT(position, >=, vector->size, INVALID_INPUT, NULL);
  157. return vector->data[position];
  158. }
  159. void vector_swap(vector_t vector, int index1, int index2)
  160. {
  161. void *aux;
  162. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  163. _ASSERT(index1, <, 0, INVALID_INPUT,);
  164. _ASSERT(index1, >=, vector->size, INVALID_INPUT,);
  165. _ASSERT(index2, <, 0, INVALID_INPUT,);
  166. _ASSERT(index2, >=, vector->size, INVALID_INPUT,);
  167. aux = vector->data[index1];
  168. vector->data[index1] = vector->data[index2];
  169. vector->data[index2] = aux;
  170. }
  171. void vector_push_front(vector_t vector, void *key)
  172. {
  173. int i;
  174. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  175. if (vector->capacity == vector->size)
  176. {
  177. _ASSERT(vector->capacity_increment, ==, 0, FULL,);
  178. vector->capacity += vector->capacity_increment;
  179. vector->data
  180. = _realloc(vector->data, vector->capacity * sizeof(void *));
  181. _ASSERT (vector->data, ==, NULL, NULL_POINTER,);
  182. }
  183. for (i = vector->size; i >= 1; i--)
  184. vector->data[i] = vector->data[i - 1];
  185. vector->data[0] = key;
  186. vector->size++;
  187. }
  188. void vector_push_back(vector_t vector, void *key)
  189. {
  190. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  191. if (vector->capacity == vector->size)
  192. {
  193. _ASSERT(vector->capacity_increment, ==, 0, FULL,);
  194. vector->capacity += vector->capacity_increment;
  195. vector->data
  196. = _realloc(vector->data, vector->capacity * sizeof(void *));
  197. _ASSERT (vector->data, ==, NULL, NULL_POINTER,);
  198. }
  199. vector->data[vector->size++] = key;
  200. }
  201. void vector_push_before(vector_t vector, void *key, void *another_key,
  202. int compare(void *x, void *y, void *context), void *context)
  203. {
  204. int i, k;
  205. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  206. _ASSERT(compare, ==, NULL, NULL_POINTER,);
  207. k = vector_search(vector, another_key, compare, context);
  208. // If i can't find F, then i push it in the vector's front.
  209. if (k == -1)
  210. {
  211. vector_push_front(vector, key);
  212. return;
  213. }
  214. if (vector->size == vector->capacity)
  215. {
  216. _ASSERT(vector->capacity_increment, ==, 0, FULL,);
  217. vector->capacity += vector->capacity_increment;
  218. vector->data
  219. = _realloc(vector->data, vector->capacity * sizeof(void *));
  220. _ASSERT (vector->data, ==, NULL, NULL_POINTER,);
  221. }
  222. for (i = vector->size; i > k; i--)
  223. vector->data[i] = vector->data[i - 1];
  224. vector->data[k] = key;
  225. vector->size++;
  226. }
  227. void vector_push_after(vector_t vector, void *E, void *F, int compare(void *x,
  228. void *y, void *context), void *context)
  229. {
  230. int i, k;
  231. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  232. _ASSERT(compare, ==, NULL, NULL_POINTER,);
  233. k = vector_search(vector, F, compare, context);
  234. // If i can't find F, then i push it in the vector's back.
  235. if (k == -1)
  236. {
  237. vector_push_back(vector, E);
  238. return;
  239. }
  240. if (vector->size == vector->capacity)
  241. {
  242. _ASSERT(vector->capacity_increment, ==, 0, FULL,);
  243. vector->capacity += vector->capacity_increment;
  244. vector->data
  245. = _realloc(vector->data, vector->capacity * sizeof(void *));
  246. _ASSERT (vector->data, ==, NULL, NULL_POINTER,);
  247. }
  248. for (i = vector->size; i > k + 1; i--)
  249. vector->data[i] = vector->data[i - 1];
  250. vector->data[k + 1] = E;
  251. vector->size++;
  252. }
  253. void *vector_remove_key(vector_t vector, void *key, int compare(void *x,
  254. void *y, void *context), void *context)
  255. {
  256. return vector_remove_key_at(vector, vector_search(vector, key, compare,
  257. context));
  258. }
  259. void *vector_remove_key_at(vector_t vector, int index)
  260. {
  261. int i;
  262. void *key;
  263. _ASSERT(vector, ==, NULL, NULL_POINTER, NULL);
  264. _ASSERT(index, <, 0, ELEMENT_NOT_FOUND, NULL);
  265. _ASSERT(index, >=, vector->size, ELEMENT_NOT_FOUND, NULL);
  266. _ASSERT(vector->size, ==, 0, EMPTY, NULL);
  267. key = vector->data[index];
  268. for (i = index; i < vector->size - 1; i++)
  269. vector->data[i] = vector->data[i + 1];
  270. vector->size--;
  271. return key;
  272. }
  273. void *vector_pop_back(vector_t vector)
  274. {
  275. _ASSERT(vector, ==, NULL, NULL_POINTER, NULL);
  276. _ASSERT(vector->size, <=, 0, NULL_POINTER, NULL);
  277. return vector->data[--vector->size];
  278. }
  279. void *vector_pop_front(vector_t vector)
  280. {
  281. _ASSERT(vector, ==, NULL, NULL_POINTER, NULL);
  282. return vector_remove_key_at(vector, 0);
  283. }
  284. int vector_search(vector_t vector, void *key, int compare(void *x, void *y,
  285. void *context), void *context)
  286. {
  287. int i;
  288. _ASSERT(vector, ==, NULL, NULL_POINTER, -1);
  289. _ASSERT(compare, ==, NULL, NULL_POINTER, -1);
  290. for (i = 0; i < vector->size; i++)
  291. if (!compare(vector->data[i], key, context))
  292. return i;
  293. return -1;
  294. }
  295. int vector_is_empty(vector_t vector)
  296. {
  297. _ASSERT(vector, ==, NULL, NULL_POINTER, -1);
  298. return vector->size == 0;
  299. }
  300. int vector_is_full(vector_t vector)
  301. {
  302. _ASSERT(vector, ==, NULL, NULL_POINTER, -1);
  303. return vector->size == vector->capacity;
  304. }
  305. void vector_sort(vector_t vector, int compare(void *x, void *y, void *context),
  306. void *context)
  307. {
  308. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  309. _ASSERT(compare, ==, NULL, NULL_POINTER,);
  310. _ASSERT(vector->size, <, 1, INVALID_INPUT,);
  311. // 1 key vector needs no sort :-)
  312. if (vector->size == 1)
  313. return;
  314. _quick_sort(vector->data, 0, vector->size - 1, compare, context);
  315. }
  316. void vector_iterate(vector_t vector, void(*key_handler)(void *key,
  317. void *context), void *context)
  318. {
  319. int i;
  320. _ASSERT(vector, ==, NULL, NULL_POINTER,);
  321. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  322. for (i = 0; i < vector->size; i++)
  323. key_handler(vector->data[i], context);
  324. }
  325. void *vector_min(vector_t vector, int compare(void *x, void *y, void *context),
  326. void *context)
  327. {
  328. void *min;
  329. int i;
  330. _ASSERT(vector, ==, NULL, NULL_POINTER, NULL);
  331. _ASSERT(compare, ==, NULL, NULL_POINTER, NULL);
  332. _ASSERT(vector->size, <=, 0, EMPTY, NULL);
  333. min = vector->data[0];
  334. for (i = 1; i < vector->size; i++)
  335. if (compare(min, vector->data[i], context) > 0)
  336. min = vector->data[i];
  337. return min;
  338. }
  339. void *vector_max(vector_t vector, int compare(void *x, void *y, void *context),
  340. void *context)
  341. {
  342. void *max;
  343. int i;
  344. _ASSERT(vector, ==, NULL, NULL_POINTER, NULL);
  345. _ASSERT(compare, ==, NULL, NULL_POINTER, NULL);
  346. _ASSERT(vector->size, <=, 0, EMPTY, NULL);
  347. max = vector->data[0];
  348. for (i = 1; i < vector->size; i++)
  349. if (compare(max, vector->data[i], context) < 0)
  350. max = vector->data[i];
  351. return max;
  352. }
  353. static void _quick_sort(void **data, int p, int r, int(*compare)(void *,
  354. void *, void *context), void *context)
  355. {
  356. int q;
  357. if (p < r)
  358. {
  359. q = _partition(data, p, r, compare, context);
  360. _quick_sort(data, p, q, compare, context);
  361. _quick_sort(data, q + 1, r, compare, context);
  362. }
  363. }
  364. static int _partition(void **data, int p, int r, int(*compare)(void *x,
  365. void *y, void *context), void *context)
  366. {
  367. int i, j;
  368. void *pivot, *aux;
  369. pivot = data[p + _rand() % (r - p)];
  370. i = p - 1;
  371. j = r + 1;
  372. while (1)
  373. {
  374. do
  375. {
  376. i++;
  377. } while (compare(data[i], pivot, context) < 0 && i < r);
  378. do
  379. {
  380. j--;
  381. } while (compare(data[j], pivot, context) > 0 && j > p);
  382. if (i >= j)
  383. return j;
  384. aux = data[i];
  385. data[i] = data[j];
  386. data[j] = aux;
  387. }
  388. }