2022-04-09 03:21:15 +03:00
|
|
|
|
#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)
|
|
|
|
|
|
{
|
2025-11-08 04:34:21 -05:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2022-04-09 03:21:15 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2025-11-08 04:34:21 -05:00
|
|
|
|
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++;
|
|
|
|
|
|
}
|
2022-04-09 03:21:15 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|