Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <time.h>
- #include <stdlib.h>
- #include <assert.h>
- #define MIN_LEN 100
- #define MAX_LEN 100000
- // обмен значений
- void swap(int* a, int* b)
- {
- int t = *a;
- *a = *b;
- *b = t;
- }
- // получить случайное число из диапазона
- int get_random(int left, int right)
- {
- int len = right - left + 1;
- assert(len > 0); // длинна интервала должна быть больше нуля
- int x = ((rand() << 15) + rand()) % len + left;
- assert(left <= x && x <= right); // проверка, что число сгенерировано в заданном интервале
- return x;
- }
- // генерация случайного массива размера size
- int * get_random_array(int size)
- {
- int * arr = calloc(size, sizeof(int));
- for(int i=0; i<size; ++i)
- arr[i] = get_random(-10000, 10000);
- return arr;
- }
- // сортировка выбором
- void selection_sort(int * a, int size)
- {
- for (int i=0; i < size-1; ++i)
- {
- // выбор минимального
- int mn = i;
- for(int j=i+1; j<size; ++j)
- if (a[j] < a[mn])
- mn = j;
- swap(&a[i], &a[mn]); // обмен значений
- }
- }
- // поиск индекса для деления массива - индекса стержневого элемента:
- // слева от этого индекса будут элементы меньше его, справа - больше
- int partition (int *a, int left, int right)
- {
- int pivot = a[right - 1]; // стержневой элемент
- int i = left; // индекс минимального элемента
- for (int j = left; j < right - 1; j++)
- {
- if (a[j] < pivot)
- {
- swap(&a[i], &a[j]);
- i++;
- }
- }
- swap(&a[i], &a[right - 1]); // ставим стержневой элемент на верное место
- return i; // возвращаем индекс стержневого элемента
- }
- // сортировка массива a на отрезке [left, right)
- void quick_sort(int * a, int left, int right)
- {
- if (left + 1 < right)
- {
- // находим индекс разделения - элемент a[pi] стоит на своем месте
- int pi = partition(a, left, right);
- // сортируем по частям
- quick_sort(a, left, pi);
- quick_sort(a, pi + 1, right);
- }
- }
- void merge(int *a, int left, int mid, int right)
- {
- // создаем массивы для слияния
- int * left_arr = (int *) malloc(sizeof(int) * (mid - left));
- int * right_arr = (int *) malloc(sizeof(int) * (right - mid));
- // копируем элементы во временные массивы
- memcpy(left_arr, &a[left], sizeof(int) * (mid - left));
- memcpy(right_arr, &a[mid], sizeof(int) * (right - mid));
- // слияние
- int i = 0, j = 0, k = left;
- while (i < mid - left && j < right - mid)
- {
- if (left_arr[i] <= right_arr[j])
- {
- a[k] = left_arr[i];
- i++;
- }
- else
- {
- a[k] = right_arr[j];
- j++;
- }
- ++k;
- }
- // сливаем остатки из левого массива
- while (i < mid - left)
- {
- a[k] = left_arr[i];
- ++i;
- ++k;
- }
- // сливаем остатки из правого массива
- while (j < right - mid)
- {
- a[k] = right_arr[j];
- ++j;
- ++k;
- }
- }
- // сортировка массива a на отрезке [left, right)
- void merge_sort(int * a, int left, int right)
- {
- if (left + 1 < right) // в массиве больше одного элемента
- {
- int mid = (left + right) / 2; // середина масива
- merge_sort(a, left, mid); // сортировка первой половины
- merge_sort(a, mid, right); // сортировка второй половины
- merge(a, left, mid, right); // слияние половин
- }
- }
- // проверка упорядоченности массива
- int check_ordering(int * a, int size)
- {
- int is_ordering = 1;
- for(int i=1; i<size; ++i)
- if (a[i] < a[i-1])
- is_ordering = 0; // если не упорядочен
- return is_ordering;
- }
- int main()
- {
- srand(time(0)); // инициализация генератора случайных чисел -> rand()
- printf("##| array size | select | quick | merge \n");
- for(int test = 0; test < 10; ++test) // число тестов = 10
- {
- // для замеров времени выполнения
- clock_t start, end;
- double cpu_time_used[3];
- int size = get_random(MIN_LEN, MAX_LEN); // размер массива случайный в заданном диапазоне
- int * src = get_random_array(size); // генерация массива
- int * copy_src = malloc(size * sizeof(int)); // копия массива
- // 1. Сортировка выбором
- memcpy(copy_src, src, size * sizeof(int)); // копируем исходный массив
- start = clock(); // стартуем
- selection_sort(copy_src, size); // сортируем
- end = clock(); // заканчиваем
- cpu_time_used[0] = ((double) (end - start)) / CLOCKS_PER_SEC; // подсчитываем время
- assert(check_ordering(copy_src, size)); // проверка упорядоченности
- // 2. Быстрая сортировка
- memcpy(copy_src, src, size * sizeof(int)); // копируем исходный массив
- start = clock(); // стартуем
- quick_sort(copy_src, 0, size); // сортируем
- end = clock(); // заканчиваем
- cpu_time_used[1] = ((double) (end - start)) / CLOCKS_PER_SEC; // подсчитываем время
- assert(check_ordering(copy_src, size)); // проверка упорядоченности
- // 3. Сортировка слиянием
- memcpy(copy_src, src, size * sizeof(int)); // копируем исходный массив
- start = clock(); // стартуем
- merge_sort(copy_src, 0, size); // сортируем
- end = clock(); // заканчиваем
- cpu_time_used[2] = ((double) (end - start)) / CLOCKS_PER_SEC; // подсчитываем время
- assert(check_ordering(copy_src, size)); // проверка упорядоченности
- // вывод строки результатов
- printf("%2d|%11d ", test+1, size);
- for(int i=0; i<3; ++i) printf("|%7.3f ", cpu_time_used[i]);
- printf("\n");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement