#include #include #include #include #include #include "macro.h" typedef void (*sorter_t)(int *arr, size_t sz); typedef struct { const char *name; sorter_t func; } sort_info_t; /* * Написать сортировку вставками (не подглядывая в инторнеты!) * arr -- целочисленный массив * sz -- размер массива */ void insert_sort(int *arr, size_t sz) { int i, j; for (i = 1; i < sz; i++){ int key = arr[i]; j = i - 1; while (j >= 0 && arr[j] > key){ arr[j + 1] = arr[j]; j--; } arr[j + 1] = key; } } void bubble_sort(int *arr, size_t sz) { int i, j; int tmp; for (i = 0; i < sz; i++) { for (j = i + 1; j < sz; j++) { if (arr[i] > arr[j]) { tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } } /* Функция для слияния двух отсортированных массивов в один. a -- указывает на первый элемент первого массива b -- указывает на первый элемент второго массива end -- указывает на первый элемент за границами второго массива Результат записывается во временный массив tmp. Первый элемент в tmp[0], второй в tmp[1] и т.д. Пример массивы a = [1, 4, 5] b = [2, 3, 6] a b end | | | \/ \/ \/ | 1 | 4 | 5 | 2 | 3 | 6 | после вызова _merge в tmp должен получиться массив | 1 | 2 | 3 | 4 | 5 | 6 | */ static void _merge(int *tmp, int *a, int *b, int *end) { int *left = a; int *right = b; int *result = tmp; while (left < b && right < end) { if (*left <= *right) { *result++ = *left++; } else { *result++ = *right++; } } while (left < b) { *result++ = *left++; } while (right < end) { *result++ = *right++; } } static void _merge_sort_int(int *tmp, int *arr, size_t n) { int half = n / 2; //индекс, который делит массивы пополам if (half > 1) _merge_sort_int(tmp, arr, half); if (n - half > 1) _merge_sort_int(tmp + half, arr + half, n - half); // "слить" два отсортированных массива в один _merge(tmp, arr, arr + half, arr + n); // Скопировать данные из временного хранилища в // оригинальный массив memcpy(arr, tmp, n * sizeof(*tmp)); } void merge_sort(int *arr, size_t sz) { int *tmp; if (sz < 2) return; tmp = malloc(sizeof(*arr) * sz); assert(tmp); _merge_sort_int(tmp, arr, sz); free(tmp); } void print_arr(int *arr, size_t n) { printf("{"); for (int i = 0; i < n; i++) { printf("%d, ", arr[i]); } printf("}\n"); } #define _S(item) {#item, item} bool test_all() { #include "test_arrays.h" TEST_ARR_INIT(testcases); sort_info_t sorters[] = { _S(insert_sort), //_S(bubble_sort), _S(merge_sort), }; int *temparr = NULL; int temparr_len = 0; int allok = 1; for (int j = 0; j < ARRSZ(sorters); j++) { sort_info_t cursort = sorters[j]; printf("[+] %s\n", cursort.name); for (int i = 0; i < ARRSZ(testcases); i++) { int len = testcases[i].len; printf("[+] testing %s\n", testcases[i].name); if (len > temparr_len) { // TODO: EER???? temparr_len = len; temparr = realloc(temparr, temparr_len * sizeof(*temparr)); assert(temparr); } memcpy(temparr, testcases[i].unsorted, sizeof(*temparr) * len); cursort.func(temparr, len); int res = memcmp(temparr, testcases[i].sorted, sizeof(*temparr) * len); if (res != 0) { allok = 0; printf("[-] arrays does not match \n"); printf("your\n"); print_arr(temparr, len); printf("original\n"); print_arr(testcases[i].sorted, len); break; } } } if (allok) { printf("[+] All OK!\n"); } if (temparr) free(temparr); return allok == 1; } int main(int argc, const char *argv[]) { test_all(); return 0; }