From d5c242a73486be83d05b3cadc90123fdadd24b73 Mon Sep 17 00:00:00 2001 From: ialina07 Date: Fri, 17 Oct 2025 20:33:28 +0000 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=A1=D0=BE=D1=80=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BA=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/homework5_17.10_tests-sort/heap_sort.py | 38 +++++ src/homework5_17.10_tests-sort/other_sorts.py | 50 +++++++ .../test_heap_sort.py | 73 ++++++++++ src/homework5_17.10_tests-sort/tests2.py | 130 ++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 src/homework5_17.10_tests-sort/heap_sort.py create mode 100644 src/homework5_17.10_tests-sort/other_sorts.py create mode 100644 src/homework5_17.10_tests-sort/test_heap_sort.py create mode 100644 src/homework5_17.10_tests-sort/tests2.py diff --git a/src/homework5_17.10_tests-sort/heap_sort.py b/src/homework5_17.10_tests-sort/heap_sort.py new file mode 100644 index 0000000..f58fe13 --- /dev/null +++ b/src/homework5_17.10_tests-sort/heap_sort.py @@ -0,0 +1,38 @@ +def heap_sort(arr): + """ + Сортировка кучей + """ + n = len(arr) + + # Строим кучу + for i in range(n // 2 - 1, -1, -1): + heap(arr, n, i) + + # Извлекаем элементы + for i in range(n - 1, 0, -1): + arr[0], arr[i] = arr[i], arr[0] # Меняем корень с последним + heap(arr, i, 0) # Просеиваем новый корень + + return arr + + +def heap(arr, n, i): + """ + Просеивание + """ + largest = i # Считаем текущий элемент наибольшим + left = 2 * i + 1 # Левый ребенок + right = 2 * i + 2 # Правый ребенок + + # Если левый ребенок существует и больше родителя + if left < n and arr[left] > arr[largest]: + largest = left + + # Если правый ребенок существует и больше наибольшего + if right < n and arr[right] > arr[largest]: + largest = right + + # Если наибольший элемент не родитель + if largest != i: + arr[i], arr[largest] = arr[largest], arr[i] # Меняем местами + heap(arr, n, largest) # Просеиваем дальше diff --git a/src/homework5_17.10_tests-sort/other_sorts.py b/src/homework5_17.10_tests-sort/other_sorts.py new file mode 100644 index 0000000..57f368b --- /dev/null +++ b/src/homework5_17.10_tests-sort/other_sorts.py @@ -0,0 +1,50 @@ +# other_sorts.py + +def bubble_sort(arr): + """ + Пузырьковая сортировка + """ + if not arr: + return arr.copy() + + arr = arr.copy() # Работаем с копией, чтобы не менять оригинал + n = len(arr) + + # Проходим по массиву n раз + for i in range(n): + # Сравниваем соседние элементы + for j in range(0, n - i - 1): + if arr[j] > arr[j + 1]: + # Меняем местами, если нужно + arr[j], arr[j + 1] = arr[j + 1], arr[j] + + return arr + +def selection_sort(arr): + """ + Сортировка выбором - ищем минимальный элемент и ставим на правильное место + """ + if not arr: + return arr.copy() + + arr = arr.copy() + n = len(arr) + + for i in range(n): + # Предполагаем, что текущий элемент - минимальный + min_index = i + + # Ищем настоящий минимальный элемент в оставшейся части + for j in range(i + 1, n): + if arr[j] < arr[min_index]: + min_index = j + + # Меняем местами с текущим элементом + arr[i], arr[min_index] = arr[min_index], arr[i] + + return arr + +# Встроенная сортировка Python для сравнения +def python_sort(arr): + """Используем встроенную сортировку как эталон""" + return sorted(arr.copy()) diff --git a/src/homework5_17.10_tests-sort/test_heap_sort.py b/src/homework5_17.10_tests-sort/test_heap_sort.py new file mode 100644 index 0000000..bb3554a --- /dev/null +++ b/src/homework5_17.10_tests-sort/test_heap_sort.py @@ -0,0 +1,73 @@ +# test_heap_sort.py +import pytest +from heap_sort import heap_sort + +# простые тесты + +def test_basic_sort(): + """Самый простой тест - обычный случай""" + arr = [4, 2, 8, 1, 5] + result = heap_sort(arr.copy()) + assert result == [1, 2, 4, 5, 8] + +def test_already_sorted(): + """Тест с уже отсортированным массивом""" + arr = [1, 2, 3, 4, 5] + result = heap_sort(arr.copy()) + assert result == [1, 2, 3, 4, 5] + +def test_reverse_sorted(): + """Тест с обратным порядком""" + arr = [5, 4, 3, 2, 1] + result = heap_sort(arr.copy()) + assert result == [1, 2, 3, 4, 5] + +# Тесты крайних случаев + +def test_empty_array(): + """Тест пустого массива""" + arr = [] + result = heap_sort(arr.copy()) + assert result == [] + +def test_single_element(): + """Тест с одним элементом""" + arr = [42] + result = heap_sort(arr.copy()) + assert result == [42] + +def test_two_elements(): + """Тест с двумя элементами""" + # Уже отсортирован + assert heap_sort([1, 2]) == [1, 2] + # Не отсортирован + assert heap_sort([2, 1]) == [1, 2] + +def test_all_same_elements(): + """Тест когда все элементы одинаковые""" + arr = [5, 5, 5, 5, 5] + result = heap_sort(arr.copy()) + assert result == [5, 5, 5, 5, 5] + +# 3. Тесты с особенными данными + +def test_with_duplicates(): + """Тест с повторяющимися числами""" + arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3] + result = heap_sort(arr.copy()) + expected = [1, 1, 2, 3, 3, 4, 5, 5, 6, 9] + assert result == expected + +def test_negative_numbers(): + """Тест с отрицательными числами""" + arr = [-3, -1, -5, 0, 2, -2] + result = heap_sort(arr.copy()) + expected = [-5, -3, -2, -1, 0, 2] + assert result == expected + +def test_mixed_numbers(): + """Тест со смешанными числами""" + arr = [10, -5, 0, 3, -2, 7] + result = heap_sort(arr.copy()) + expected = [-5, -2, 0, 3, 7, 10] + assert result == expected diff --git a/src/homework5_17.10_tests-sort/tests2.py b/src/homework5_17.10_tests-sort/tests2.py new file mode 100644 index 0000000..af1803e --- /dev/null +++ b/src/homework5_17.10_tests-sort/tests2.py @@ -0,0 +1,130 @@ +# tests2.py +import pytest +import random +from other_sorts import bubble_sort, selection_sort, python_sort +from heap_sort import heap_sort + +# 1. Основное свойство: ВСЕ ТРИ сортировки дают одинаковый результат + +def test_all_three_sorts_same_result_simple(): + """Все три сортировки дают одинаковый результат на простом массиве""" + arr = [4, 2, 8, 1, 5] + + bubble_result = bubble_sort(arr) + selection_result = selection_sort(arr) + heap_result = heap_sort(arr) + python_result = python_sort(arr) + + # Все должны быть равны + assert bubble_result == selection_result == heap_result == python_result + assert heap_result == [1, 2, 4, 5, 8] + +def test_all_three_sorts_same_result_random(): + """Тестируем на случайных массивах разного размера""" + for size in [5, 10, 15, 20, 25]: + arr = [random.randint(1, 100) for _ in range(size)] + + bubble_result = bubble_sort(arr) + selection_result = selection_sort(arr) + heap_result = heap_sort(arr) + python_result = python_sort(arr) + + # Проверяем что все результаты одинаковые + assert bubble_result == selection_result == heap_result == python_result + + # И что результат отсортирован + for i in range(len(bubble_result) - 1): + assert bubble_result[i] <= bubble_result[i + 1] + +# 2. Свойство: идемпотентность всех трёх сортировок + +def test_idempotence_all_three(): + """Все три сортировки идемпотентны""" + arr = [random.randint(1, 50) for _ in range(10)] + + # Тестируем каждую сортировку + for sort_func in [bubble_sort, selection_sort, heap_sort]: + first_sort = sort_func(arr) + second_sort = sort_func(first_sort) + + # Должны получить тот же результат + assert first_sort == second_sort, f"Сортировка {sort_func.__name__} не идемпотентна" + +def test_idempotence_cross_check(): + """Перекрёстная проверка идемпотентности""" + arr = [3, 1, 4, 1, 5, 9, 2, 6] + + bubble_once = bubble_sort(arr) + bubble_twice = bubble_sort(bubble_once) + + selection_once = selection_sort(arr) + selection_twice = selection_sort(selection_once) + + heap_once = heap_sort(arr) + heap_twice = heap_sort(heap_once) + + # Все должны быть равны после повторной сортировки + assert bubble_once == bubble_twice + assert selection_once == selection_twice + assert heap_once == heap_twice + assert bubble_once == selection_once == heap_once + +# 3. Свойство: сохранение элементов во всех трёх сортировках + +def test_preserves_all_elements_all_three(): + """Все три сортировки сохраняют все элементы""" + arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3] + + bubble_result = bubble_sort(arr) + selection_result = selection_sort(arr) + heap_result = heap_sort(arr) + + # Проверяем что все содержат одинаковые элементы + assert set(arr) == set(bubble_result) == set(selection_result) == set(heap_result) + assert len(arr) == len(bubble_result) == len(selection_result) == len(heap_result) + + # Проверяем количество каждого элемента + for num in set(arr): + original_count = arr.count(num) + assert original_count == bubble_result.count(num) + assert original_count == selection_result.count(num) + assert original_count == heap_result.count(num) + +# 4. Свойство: работа с разными типами данных + +def test_negative_numbers_all_three(): + """Все три сортировки работают с отрицательными числами""" + arr = [-3, -1, -5, 0, 2, -2, 7, -8, 4, -1] + + bubble_result = bubble_sort(arr) + selection_result = selection_sort(arr) + heap_result = heap_sort(arr) + python_result = python_sort(arr) + + expected = [-8, -5, -3, -2, -1, -1, 0, 2, 4, 7] + + assert bubble_result == expected + assert selection_result == expected + assert heap_result == expected + assert python_result == expected + +def test_duplicates_all_three(): + """Все три сортировки корректно обрабатывают дубликаты""" + arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 1] + + bubble_result = bubble_sort(arr) + selection_result = selection_sort(arr) + heap_result = heap_sort(arr) + + # Все должны дать одинаковый результат с дубликатами + assert bubble_result == selection_result == heap_result + + # Проверяем что дубликаты на месте + assert bubble_result.count(1) == 3 + assert bubble_result.count(3) == 2 + assert bubble_result.count(5) == 3 + + + + +