1
0
forked from 131/lab4_sort
Files
lab4_sort/sort.c
2022-04-09 03:21:15 +03:00

174 lines
3.8 KiB
C

#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#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)
{
// <YOURCODE>
}
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)
{
// <YOURCODE>
}
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;
}