1 1 `new file mode 100644` ... ... `@@ -0,0 +1,87 @@` 1 `+/**` 2 `+ * Copyright © 2016 Xavier G. ` 3 `+ * This work is free. You can redistribute it and/or modify it under the` 4 `+ * terms of the Do What The Fuck You Want To Public License, Version 2,` 5 `+ * as published by Sam Hocevar. See the COPYING file for more details.` 6 `+ */` 7 `+` 8 `+void array_sort(unsigned int **array, unsigned int count);` 9 `+#define ARRAY_SORT 1` 10 `+#include "common.c"` 11 `+` 12 `+#define min(a, b) ((a < b) ? (a) : (b))` 13 `+` 14 `+/*` 15 `+ * Implementation of merge sort:` 16 `+ */` 17 `+void array_sort(unsigned int **array, unsigned int count) {` 18 `+ unsigned int width, i, left_i, right_i, left_end, right_end, j;` 19 `+ unsigned int *current, *other, *swap;` 20 `+` 21 `+ /* Do nothing unless there are at least two items to sort: */` 22 `+ if (count < 2) return;` 23 `+` 24 `+ /* Although in-place (or more precisely, in-place-like) variants exist,` 25 `+ merge sort is not an in-place algorithm per se. */` 26 `+ current = *array;` 27 `+ /* Reserve enough space to copy the whole source array; indeed, merge sort's` 28 `+ worst case space complexity is O(n). */` 29 `+ other = malloc(sizeof(unsigned int) * count);` 30 `+` 31 `+ /* We start with an array of n sorted, 1-item arrays. */` 32 `+ for (width = 1; width < count; width *= 2) {` 33 `+ VERBOSE(1, " Merging pairs of sorted, %u-item(s) arrays, \n", width);` 34 `+ for (i = 0; i < count; i += 2 * width) {` 35 `+ left_i = i;` 36 `+ right_i = min(left_i + width, count - 1);` 37 `+ left_end = min(left_i + width - 1, count - 1);` 38 `+ right_end = min(right_i + width - 1, count - 1);` 39 `+ VERBOSE(2, " Merging [%u-%u] and [%u-%u]\n", left_i, left_end, right_i, right_end);` 40 `+` 41 `+ /* Spare a few comparisons and assignments if there is only one item: */` 42 `+ if (left_i == right_end) {` 43 `+ VERBOSE(3, " Simply copying [%u] here\n", left_i);` 44 `+ other[left_i] = current[left_i];` 45 `+ continue;` 46 `+ }` 47 `+` 48 `+ /* Do the same if there is actually only one pair: */` 49 `+ if (left_end == right_end) {` 50 `+ VERBOSE(3, " Simply copying [%u-%u] here\n", left_i, left_end);` 51 `+ for (j = left_i; j <= left_end; ++ j) {` 52 `+ other[j] = current[j];` 53 `+ }` 54 `+ continue;` 55 `+ }` 56 `+` 57 `+ for (j = left_i; j <= right_end; ++ j) {` 58 `+ if (left_i <= left_end && right_i <= right_end) {` 59 `+ /* There remain items on both sides: compare them: */` 60 `+ if (current[left_i] <= current[right_i]) {` 61 `+ other[j] = current[left_i];` 62 `+ ++ left_i;` 63 `+ }` 64 `+ else {` 65 `+ other[j] = current[right_i];` 66 `+ ++ right_i;` 67 `+ }` 68 `+ }` 69 `+ else if (left_i > left_end) {` 70 `+ /* There remain no more items on the left side: */` 71 `+ other[j] = current[right_i];` 72 `+ ++ right_i;` 73 `+ }` 74 `+ else if (right_i > right_end) {` 75 `+ /* There remain no more items on the right side: */` 76 `+ other[j] = current[left_i];` 77 `+ ++ left_i;` 78 `+ }` 79 `+ }` 80 `+ }` 81 `+ /* Swap the roles of our arrays: */` 82 `+ swap = current;` 83 `+ current = other;` 84 `+ other = swap;` 85 `+ }` 86 `+ *array = current;` 87 `+}`