arraylist.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /* origin code from stackexchange
  2. https://codereview.stackexchange.com/questions/245941/arraylist-implementation-in-c
  3. https://codereview.stackexchange.com/questions/160434/c-generic-arraylist-dynamic-array-implementations
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stdarg.h>
  8. #include <stdbool.h>
  9. #include <string.h>
  10. #ifndef STRUCT_ARRAYLIST_H
  11. #define STRUCT_ARRAYLIST_H
  12. typedef struct {
  13. int capacity;
  14. int size;
  15. int *arr;
  16. } List;
  17. typedef List* ListPtr;
  18. ListPtr initializeWithCapacity(int capacity) {
  19. ListPtr a = malloc(sizeof *a);
  20. a->capacity = capacity;
  21. a->arr = malloc(a->capacity * sizeof *(a->arr));
  22. a->size = 0;
  23. return a;
  24. }
  25. bool ensureCapacity(ListPtr a, int minCapacity) {
  26. if(minCapacity > a->capacity) {
  27. a->capacity = a->capacity << 1; // 增长两倍容量
  28. if(a->capacity < minCapacity)
  29. a->capacity = minCapacity;
  30. // 按照新的容量空间,重新分配内存(保留原有数据)
  31. a->arr = realloc(a->arr, a->capacity * sizeof(int));
  32. }
  33. return true;
  34. }
  35. bool append(ListPtr a, int n) {
  36. ensureCapacity(a, a->size + 1); //确保容量不小于 数据量 + 1
  37. a->arr[a->size++] = n;
  38. return true;
  39. }
  40. int get(ListPtr a, int index) {
  41. if(index < 0) // 允许从尾部反向访问
  42. index = a->size + index;
  43. if(index >= a->size || index < 0)
  44. return -1; // 异常条件返回 -1
  45. return a->arr[index];
  46. }
  47. bool set(ListPtr a, int index, int value) {
  48. if(index < 0) // 允许从尾部反向访问
  49. index = a->size + index;
  50. if(index >= a->size || index < 0)
  51. return false; // 异常条件返回 false
  52. a->arr[index] = value;
  53. return true;
  54. }
  55. bool pop(ListPtr a, int index) {
  56. if(index < 0)
  57. index = a->size + index;
  58. if(index >= a->size || index < 0)
  59. return false;
  60. for(int i = index; i < a->size-1; i++)
  61. a->arr[i] = a->arr[i+1];
  62. a->size--;
  63. return true;
  64. }
  65. bool clear(ListPtr a) {
  66. free(a->arr);
  67. a->arr = malloc(0);
  68. a->capacity = 0;
  69. a->size = 0;
  70. return true;
  71. }
  72. int len(ListPtr a) {
  73. return a->size;
  74. }
  75. int cap(ListPtr a) {
  76. return a->capacity;
  77. }
  78. ListPtr initialize() {
  79. return initializeWithCapacity(10);
  80. }
  81. ListPtr initializeWithArray(int arr[], int length) {
  82. ListPtr a = initializeWithCapacity(length);
  83. for(int i = 0; i < length; i++)
  84. a->arr[a->size++] = arr[i];
  85. return a;
  86. }
  87. ListPtr values(int n, ...) {
  88. va_list valist;
  89. va_start(valist, n);
  90. ListPtr a = initializeWithCapacity(n);
  91. for(int i = 0; i < n; i++) {
  92. a->arr[a->size++] = va_arg(valist, int);
  93. }
  94. va_end(valist);
  95. return a;
  96. }
  97. ListPtr range(int start, int stop, int step) {
  98. if(step == 0)
  99. return initializeWithCapacity(0);
  100. ListPtr a = initializeWithCapacity( abs(stop - start) / abs(step) + 1 );
  101. if(step > 0) {
  102. for(int i = start; i < stop; i += step)
  103. a->arr[a->size++] = i;
  104. }
  105. else {
  106. for(int i = start; i > stop; i += step)
  107. a->arr[a->size++] = i;
  108. }
  109. return a;
  110. }
  111. ListPtr slice(ListPtr a, int start, int stop, int step) {
  112. if(step == 0 || start < 0 || stop < -1 || start >= a->size || stop >= a->size)
  113. return initializeWithCapacity(0);
  114. ListPtr b = initializeWithCapacity( abs(stop - start) / abs(step) + 1 );
  115. if(step > 0) {
  116. for(int i = start; i < stop; i += step)
  117. b->arr[b->size++] = a->arr[i];
  118. }
  119. else {
  120. for(int i = start; i > stop; i += step)
  121. b->arr[b->size++] = a->arr[i];
  122. }
  123. return b;
  124. }
  125. bool trimToSize(ListPtr a) {
  126. a->capacity = a->size;
  127. a->arr = realloc(a->arr, a->capacity * sizeof *(a->arr));
  128. return true;
  129. }
  130. bool fill(ListPtr a, int value, int n) {
  131. ensureCapacity(a, n);
  132. a->size = n;
  133. for(int i = 0; i < n; i++) {
  134. a->arr[i] = value;
  135. }
  136. return true;
  137. }
  138. bool extendWithArray(ListPtr a, int arr[], int length) {
  139. ensureCapacity(a, a->size + length);
  140. for(int i = 0; i < length; i++)
  141. a->arr[a->size++] = arr[i];
  142. return true;
  143. }
  144. bool extend(ListPtr a, ListPtr b) {
  145. extendWithArray(a, b->arr, b->size);
  146. return true;
  147. }
  148. bool insert(ListPtr a, int index, int n) {
  149. if(index < 0)
  150. index = a->size + index;
  151. if(index > a->size || index < 0)
  152. return false;
  153. if(index == a->size) {
  154. append(a, n);
  155. return true;
  156. }
  157. ensureCapacity(a, a->size + 1);
  158. for(int i = a->size; i > index; i--) {
  159. a->arr[i] = a->arr[i-1];
  160. }
  161. a->arr[index] = n;
  162. a->size++;
  163. return true;
  164. }
  165. ListPtr copy(ListPtr a) {
  166. ListPtr b = initializeWithCapacity(a->capacity);
  167. extendWithArray(b, a->arr, a->size);
  168. return b;
  169. }
  170. int indexOf(ListPtr a, int value) {
  171. for(int i = 0; i < a->size; i++) {
  172. if(a->arr[i] == value)
  173. return i;
  174. }
  175. return -1;
  176. }
  177. int lastIndexOf(ListPtr a, int value) {
  178. for(int i = a->size - 1; i >= 0; i--) {
  179. if(a->arr[i] == value)
  180. return i;
  181. }
  182. return -1;
  183. }
  184. int binarySearch(ListPtr a, int value) {
  185. int lower = 0, upper = a->size - 1, mid = 0;
  186. while(lower <= upper) {
  187. mid = (lower + upper) / 2;
  188. if(a->arr[mid] == value)
  189. return mid;
  190. else if(a->arr[mid] < value)
  191. lower = mid + 1;
  192. else
  193. upper = mid - 1;
  194. }
  195. return -1;
  196. }
  197. bool contains(ListPtr a, int value) {
  198. return indexOf(a, value) >= 0;
  199. }
  200. bool isEmpty(ListPtr a) {
  201. return a->size == 0;
  202. }
  203. bool isEqual(ListPtr a, ListPtr b) {
  204. if(a->size != b->size)
  205. return false;
  206. for(int i = 0; i < a->size; i++) {
  207. if(a->arr[i] != b->arr[i])
  208. return false;
  209. }
  210. return true;
  211. }
  212. bool delete(ListPtr a, int value) {
  213. int index = indexOf(a, value);
  214. if(index == -1)
  215. return false;
  216. return pop(a, index);
  217. }
  218. bool reverse(ListPtr a) {
  219. for(int start = 0, stop = a->size-1; start < stop; start++, stop--) {
  220. int t = a->arr[start];
  221. a->arr[start] = a->arr[stop];
  222. a->arr[stop] = t;
  223. }
  224. return true;
  225. }
  226. bool replace(ListPtr a, int oldValue, int newValue) {
  227. for(int i = 0; i < a->size; i++) {
  228. if(a->arr[i] == oldValue)
  229. a->arr[i] = newValue;
  230. }
  231. return true;
  232. }
  233. /*Code for sorting begins*/
  234. int comparisonFunctionAscending (const void *a, const void *b) {
  235. return ( *(int*)a - *(int*)b );
  236. }
  237. int comparisonFunctionDescending (const void *a, const void *b) {
  238. return ( *(int*)b - *(int*)a );
  239. }
  240. bool sort(ListPtr a) {
  241. qsort(a->arr, a->size, sizeof(int), comparisonFunctionAscending);
  242. return true;
  243. }
  244. bool sortReverse(ListPtr a) {
  245. qsort(a->arr, a->size, sizeof(int), comparisonFunctionDescending);
  246. return true;
  247. }
  248. /*Code for sorting ends*/
  249. int count(ListPtr a, int value) {
  250. int c = 0;
  251. for(int i = 0; i < a->size; i++) {
  252. if(a->arr[i] == value)
  253. c++;
  254. }
  255. return c;
  256. }
  257. int sum(ListPtr a) {
  258. int s = 0;
  259. for(int i = 0; i < a->size; i++)
  260. s += a->arr[i];
  261. return s;
  262. }
  263. int* toArray(ListPtr a) {
  264. int *b = malloc(a->size * sizeof *b);
  265. for(int i = 0; i < a->size; i++)
  266. b[i] = a->arr[i];
  267. return b;
  268. }
  269. char* toString(ListPtr a) {
  270. int iMax = a->size - 1;
  271. if(iMax == -1)
  272. return "[]";
  273. char *str = malloc( (a->size * 12 + 1) * sizeof *str );
  274. strcpy(str, "[");
  275. for(int i = 0; ; i++) {
  276. char temp[11];
  277. sprintf(temp, "%d", a->arr[i]);
  278. strcat(str, temp);
  279. if(i == iMax) {
  280. strcat(str, "]");
  281. return str;
  282. }
  283. strcat(str, ", ");
  284. }
  285. }
  286. bool display(ListPtr a) {
  287. printf("%s \n", toString(a));
  288. return true;
  289. }
  290. #endif