Добавил:
Рад, если кому-то помог Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
1
Добавлен:
01.11.2025
Размер:
10.81 Кб
Скачать
#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;
}
Соседние файлы в папке Лаба8