Добавил:
vvrstcnho
Рад, если кому-то помог
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторные работы С (для ИВТ) / Готовые лабы С / Лаба8 / Laba 8
.c#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// ============================ СОРТИРОВКИ ============================
// 1. Челночная сортировка
void shuttle_sort(int *a, int n) {
int i, j, temp;
for (i = 1; i < n; i++) {
if (a[i] < a[i - 1]) {
temp = a[i];
a[i] = a[i - 1];
a[i - 1] = temp;
for (j = i - 1; j > 0 && a[j] < a[j - 1]; j--) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
}
// 2. Сортировка Шелла
void shell_sort(int *a, int n) {
int h, i, j, temp;
// Вычисление начального шага
for (h = 1; h <= n / 9; h = 3 * h + 1);
for (; h > 0; h /= 3) {
for (i = h; i < n; i++) {
temp = a[i];
for (j = i; j >= h && a[j - h] > temp; j -= h) {
a[j] = a[j - h];
}
a[j] = temp;
}
}
}
// 3. Быстрая сортировка
void quick_sort(int *a, int left, int right) {
if (left >= right) return;
int i = left, j = right;
int pivot = a[(left + right) / 2];
int temp;
while (i <= j) {
while (a[i] < pivot) i++;
while (a[j] > pivot) j--;
if (i <= j) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
quick_sort(a, left, j);
quick_sort(a, i, right);
}
// Вспомогательная функция для быстрой сортировки
void quick_sort_wrapper(int *a, int n) {
quick_sort(a, 0, n - 1);
}
// 4. Центрированная вставка
void centered_insertion(int *a, int n) {
if (n == 0) return;
int *work = (int*)malloc(n * sizeof(int));
if (work == NULL) {
printf("Memory allocation error!\n");
return;
}
int mid = n / 2;
int left = mid, right = mid;
// Первый элемент помещаем в центр
work[mid] = a[0];
for (int i = 1; i < n; i++) {
if (a[i] < work[mid]) {
// Вставка в левую ветвь
int j = left;
while (j < mid && a[i] > work[j]) j++;
// Сдвиг элементов вправо
for (int k = left; k < j; k++) {
work[k - 1] = work[k];
}
work[j - 1] = a[i];
left--;
} else {
// Вставка в правую ветвь
int j = right;
while (j > mid && a[i] < work[j]) j--;
// Сдвиг элементов влево
for (int k = right; k > j; k--) {
work[k + 1] = work[k];
}
work[j + 1] = a[i];
right++;
}
}
// Копируем результат обратно в исходный массив
for (int i = 0; i < n; i++) {
a[i] = work[i];
}
free(work);
}
// ============================ ПОИСК ============================
// 1. Бинарный поиск (итеративный)
int binary_search_iterative(int *a, int n, int key) {
int left = 0, right = n - 1, mid;
while (left <= right) {
mid = left + (right - left) / 2;
if (a[mid] == key) {
return mid; // Найден
} else if (a[mid] < key) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // Не найден
}
// 2. Бинарный поиск (рекурсивный)
int binary_search_recursive(int *a, int left, int right, int key) {
if (left > right) {
return -1; // Базовый случай - не найден
}
int mid = left + (right - left) / 2;
if (a[mid] == key) {
return mid; // Найден
} else if (a[mid] < key) {
return binary_search_recursive(a, mid + 1, right, key);
} else {
return binary_search_recursive(a, left, mid - 1, key);
}
}
// Вспомогательная функция для рекурсивного бинарного поиска
int binary_search_recursive_wrapper(int *a, int n, int key) {
return binary_search_recursive(a, 0, n - 1, key);
}
// 3. Интерполяционный поиск
int interpolation_search(int *a, int n, int key) {
int left = 0, right = n - 1, pos;
while (left <= right && key >= a[left] && key <= a[right]) {
if (a[right] == a[left]) {
// Все элементы одинаковые
if (a[left] == key) return left;
else return -1;
}
// Формула интерполяции
pos = left + ((key - a[left]) * (right - left)) / (a[right] - a[left]);
if (pos < left || pos > right) {
break; // Защита от выхода за границы
}
if (a[pos] == key) {
return pos; // Найден
} else if (a[pos] < key) {
left = pos + 1;
} else {
right = pos - 1;
}
}
return -1; // Не найден
}
// ============================ ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ============================
// Печать массива (первые, средние и последние элементы)
void print_array(const char *msg, int *a, int n) {
printf("%s\n", msg);
if (n <= 20) {
// Печатаем весь массив если он маленький
for (int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
} else {
// Печатаем первые 10 элементов
printf("First 10: ");
for (int i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
printf("\n");
// Печатаем средние 10 элементов
printf("Middle 10: ");
for (int i = n/2 - 5; i < n/2 + 5; i++) {
printf("%d ", a[i]);
}
printf("\n");
// Печатаем последние 10 элементов
printf("Last 10: ");
for (int i = n - 10; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
printf("\n");
}
// Проверка отсортированности массива
int is_sorted(int *a, int n) {
for (int i = 1; i < n; i++) {
if (a[i] < a[i - 1]) {
return 0; // Не отсортирован
}
}
return 1; // Отсортирован
}
// ============================ ТЕСТИРОВАНИЕ ============================
void test_sort_search(int n, int m,
void (*sort_func)(int*, int),
int (*search_func)(int*, int, int),
const char *sort_name,
const char *search_name) {
printf("\n----------------------------------------\n");
printf("TEST: %s + %s\n", sort_name, search_name);
printf("Array size: %d, Keys: %d\n", n, m);
// Выделение памяти
int *a = (int*)malloc(n * sizeof(int));
int *keys = (int*)malloc(m * sizeof(int));
if (a == NULL || keys == NULL) {
printf("Memory allocation error!\n");
free(a);
free(keys);
return;
}
// Заполнение массива случайными числами
srand(time(NULL));
for (int i = 0; i < n; i++) {
a[i] = rand() % n;
}
print_array("BEFORE SORTING:", a, n);
// Тестирование сортировки
clock_t start = clock();
sort_func(a, n);
clock_t end = clock();
double sort_time = (double)(end - start) / CLOCKS_PER_SEC;
// Проверка корректности сортировки
if (!is_sorted(a, n)) {
printf("SORTING ERROR!\n");
}
print_array("AFTER SORTING:", a, n);
printf("Sorting time: %.4f seconds\n", sort_time);
// Генерация ключей для поиска
for (int i = 0; i < m; i++) {
keys[i] = rand() % (n + m); // Ключи могут быть за пределами массива
}
// Тестирование поиска
start = clock();
int found = 0;
for (int i = 0; i < m; i++) {
int pos = search_func(a, n, keys[i]);
if (pos != -1) found++;
}
end = clock();
double search_time = (double)(end - start) / CLOCKS_PER_SEC;
printf("Keys found: %d/%d (%.1f%%)\n", found, m, (double)found/m*100);
printf("Search time: %.4f seconds\n", search_time);
printf("Total time: %.4f seconds\n", sort_time + search_time);
free(a);
free(keys);
}
// ============================ ГЛАВНАЯ ФУНКЦИЯ ============================
int main() {
int n = 1000; // размер массива
int m = 100; // количество ключей для поиска
printf("Test parameters:\n");
printf("- Array size: %d elements\n", n);
printf("- Number of keys: %d\n", m);
printf("\n");
// 1. Челночная сортировка + бинарный поиск (итеративный)
test_sort_search(n, m, shuttle_sort, binary_search_iterative,
"Shuttle Sort", "Binary Search Iterative");
// 2. Сортировка Шелла + бинарный поиск (рекурсивный)
test_sort_search(n, m, shell_sort, binary_search_recursive_wrapper,
"Shell Sort", "Binary Search Recursive");
// 3. Быстрая сортировка + бинарный поиск (итеративный)
test_sort_search(n, m, quick_sort_wrapper, binary_search_iterative,
"Quick Sort", "Binary Search Iterative");
// 4. Центрированная вставка + интерполяционный поиск
test_sort_search(n, m, centered_insertion, interpolation_search,
"Centered Insertion", "Interpolation Search");
printf("\n----------------------------------------\n");
printf("ALL TESTS COMPLETED SUCCESSFULLY!\n");
printf("==============================\n");
return 0;
} 