commit 6720dc58cd078bfa480cf9093023c28e061cfc07 Author: dzruyk Date: Sat Apr 9 03:21:15 2022 +0300 init commit diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5c16d53 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/sort_test", + "args": [""], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..0b9fc33 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,14 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "shell", + "label": "C/C++: gcc build", + "command": "make", + "problemMatcher": [ + "$gcc" + ], + "group": "build", + } + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..df6b5a2 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +sort_bin=./sort_test +CFLAGS=-Wall -ggdb + +all: $(sort_bin) + +$(sort_bin): sort.o + $(CC) $(CFLAGS) $^ -o $@ + +clean: + rm *.o $(sort_bin) + +test: $(heap_bin) $(arrheap_bin) $(vector_bin) $(list_bin) + $(vector_bin) + $(list_bin) + $(hash_bin) + $(heap_bin) + $(arrheap_bin) diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..1a45907 --- /dev/null +++ b/README.txt @@ -0,0 +1,18 @@ +Сортировки +---------- + +Задачи: + +* Склонить git-репозиторий http://lab.amplab.ru/lab3_sort.git/ + + Весь нужный код находится в файле sort.c + Функция main вызвает функцию test_all, которая тестирует различные реализации + алгоритмов сортировки. + +* Написать сортировку вставками (постараться не подглядывать в интернеты!) + реализовав функцию insert_sort + +* разобраться в работе функции merge_sort, которая + сортирует массив методом слияния. + +* Написать реализацию функции _merge для совмещения двух кусочков массива в один diff --git a/macro.h b/macro.h new file mode 100644 index 0000000..fae0ee1 --- /dev/null +++ b/macro.h @@ -0,0 +1,15 @@ +#pragma once + +#define ARRSZ(arr) (sizeof(arr) / sizeof(*arr)) + +#define SWAP(a, b, type) do { \ + type tmp; \ + tmp = a; \ + a = b; \ + b = tmp; \ +} while(0) + + +#define ARR_FOREACH(arr, item) \ + for (item = arr; item != arr + ARRSZ(arr) * sizeof(*item); item++) + diff --git a/sort.c b/sort.c new file mode 100644 index 0000000..b43ee6e --- /dev/null +++ b/sort.c @@ -0,0 +1,173 @@ +#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) +{ + // +} + +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) +{ + // +} + +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; +} diff --git a/test_arrays.h b/test_arrays.h new file mode 100644 index 0000000..ca64552 --- /dev/null +++ b/test_arrays.h @@ -0,0 +1,50 @@ + +struct test_case { + char *name; + int *unsorted; + int *sorted; + int len; +}; + +#define TEST_ARR_INIT(arrname) \ + struct test_case arrname[] = { \ + {"null_array_test", _test0, _res0, ARRSZ(_test0)}, \ + {"single_element_test", _test1, _res1, ARRSZ(_test1)}, \ + {"simple1", _test2, _res2, ARRSZ(_test2)}, \ + {"simple2", _test3, _res3, ARRSZ(_test3)}, \ + } + +int _test0[] = {}; +int _res0[] = {}; + +int _test1[] = {0}; +int _res1[] = {0}; + +int _test2[] = { + 504, 9245, 3289, 7184, 5410, 2261, 6503, 4235, 8415, 827, 3420, 9730, 9428, 7215, 273, 8245, 6529, 7690, 2846, 4412 +}; + +int _res2[] = { + 273, 504, 827, 2261, 2846, 3289, 3420, 4235, 4412, 5410, 6503, 6529, 7184, 7215, 7690, 8245, 8415, 9245, 9428, 9730 +}; + +int _test3[] = { + 98331, 13683, 97511, 15357, 56393, 89831, 7904, 74770, 15487, 23946, 32739, 1128, 56514, 33644, 19980, 52769, + 56319, 26639, 88561, 67117, 73982, 75835, 40059, 77485, 71858, 92894, 73648, 96021, 7269, 15689, 44994, 49276, + 17429, 46491, 10271, 16281, 97307, 86615, 10603, 8643, 18066, 79695, 82937, 52337, 42199, 44473, 96145, 19807, + 17431, 91971, 18274, 54676, 6445, 65513, 26458, 88252, 83712, 66622, 76657, 57946, 98056, 16875, 40892, 19293, + 14820, 19020, 46293, 66041, 25840, 18989, 89892, 12201, 34180, 59271, 14512, 35198, 94562, 11379, 96972, 64998, + 21820, 24021, 44192, 87773, 93483, 22016, 96859, 43760, 33447, 29202, 93463, 57147, 87856, 24973, 14629, 68993, + 96040, 63305, 97917, 2874, +}; + +int _res3[] = { + 1128, 2874, 6445, 7269, 7904, 8643, 10271, 10603, 11379, 12201, 13683, 14512, 14629, 14820, 15357, 15487, + 15689, 16281, 16875, 17429, 17431, 18066, 18274, 18989, 19020, 19293, 19807, 19980, 21820, 22016, 23946, 24021, + 24973, 25840, 26458, 26639, 29202, 32739, 33447, 33644, 34180, 35198, 40059, 40892, 42199, 43760, 44192, 44473, + 44994, 46293, 46491, 49276, 52337, 52769, 54676, 56319, 56393, 56514, 57147, 57946, 59271, 63305, 64998, 65513, + 66041, 66622, 67117, 68993, 71858, 73648, 73982, 74770, 75835, 76657, 77485, 79695, 82937, 83712, 86615, 87773, + 87856, 88252, 88561, 89831, 89892, 91971, 92894, 93463, 93483, 94562, 96021, 96040, 96145, 96859, 96972, 97307, + 97511, 97917, 98056, 98331 +}; +