From c9a6246c66118fde8820f5aff8b1daff6272491a Mon Sep 17 00:00:00 2001 From: anna shalahina Date: Fri, 17 Oct 2025 22:51:31 +0300 Subject: [PATCH 1/2] add heapsort --- src/__init__.py | 0 src/heapsort.py | 44 ++++++++++++++++++++++++++++++ tests/__init__.py | 0 tests/conftest.py | 31 +++++++++++++++++++++ tests/test_heapsort.py | 61 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 src/__init__.py create mode 100644 src/heapsort.py create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_heapsort.py diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/heapsort.py b/src/heapsort.py new file mode 100644 index 0000000..08b07ec --- /dev/null +++ b/src/heapsort.py @@ -0,0 +1,44 @@ +def swap(arr, i, j): + arr[i], arr[j] = arr[j], arr[i] + + +def sift_down(arr, i, upper): + while True: + L, r = i * 2 + 1, i * 2 + 2 + if max(L, r) < upper: + if arr[i] >= max(arr[L], arr[r]): + break + elif arr[L] > arr[r]: + swap(arr, i, L) + i = L + else: + swap(arr, i, r) + i = r + elif L < upper: + if arr[L] > arr[i]: + swap(arr, i, L) + i = L + else: + break + elif r < upper: + if arr[r] > arr[i]: + swap(arr, i, r) + i = r + else: + break + else: + break + + +def heapsort(arr): + for j in range((len(arr) - 2) // 2, -1, -1): + sift_down(arr, j, len(arr)) + + for end in range(len(arr) - 1, 0, -1): + swap(arr, 0, end) + sift_down(arr, 0, end) + + +arr = [4, 90, 6, 14, 35, 7] +heapsort(arr) +print(arr) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..3bae518 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,31 @@ +import pytest +import random + + +@pytest.fixture +def sample_list(): + return [4, 90, 6, 14, 35, 7] + + +@pytest.fixture +def many_duplicates(): + return [i % 6 for i in range(200)] + + +@pytest.fixture( + params=[ + [], + [1], + [2, 1], + [5, 5, 5, 5], + [10, -1, 3, 5], + ] +) +def case_list(request): + return request.param + + +@pytest.fixture +def random_list(): + random.seed(52) + return [random.randint(-1000, 1000) for i in range(100)] diff --git a/tests/test_heapsort.py b/tests/test_heapsort.py new file mode 100644 index 0000000..5950eb3 --- /dev/null +++ b/tests/test_heapsort.py @@ -0,0 +1,61 @@ +import pytest +from src.heapsort import heapsort + + +def test_heapsort(): + a = [3, 1, 2] + heapsort(a) + assert a == [1, 2, 3] + + +def test_negative_heapsort(): + a = [-3, -1, -2] + heapsort(a) + assert a == [-3, -2, -1] + + +@pytest.mark.parametrize( + "input_list, expected", + [ + ([], []), + ([1], [1]), + ([2, 2, 2], [2, 2, 2]), + ([4, 3, 2, 1], [1, 2, 3, 4]), + ], +) +def test_parametrized(input_list, expected): + arr = list(input_list) + heapsort(arr) + assert arr == expected + + +def test_duplicates_and_negatives(): + arr = [0, -1, 5, -1, 3, 0, 5] + expected = sorted(arr) + heapsort(arr) + assert arr == expected + + +def test_heapsort_sample_list(sample_list): + arr = sample_list.copy() + heapsort(arr) + assert arr == sorted(sample_list) + + +def test_heapsort_many_duplicates(many_duplicates): + arr = many_duplicates.copy() + heapsort(arr) + assert arr == sorted(many_duplicates) + + +def test_heapsort_cases(case_list): + arr = list(case_list) + heapsort(arr) + assert arr == sorted(case_list) + + +def test_heapsort_random(random_list): + a = random_list.copy() + b = list(a) + heapsort(b) + assert b == sorted(a) From c426e5bf198489ee34e4ff955b70e7498483379b Mon Sep 17 00:00:00 2001 From: anna shalahina Date: Sat, 25 Oct 2025 20:46:02 +0300 Subject: [PATCH 2/2] changed heapsort.py --- src/heapsort.py | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/heapsort.py b/src/heapsort.py index 08b07ec..cfce9f1 100644 --- a/src/heapsort.py +++ b/src/heapsort.py @@ -4,30 +4,27 @@ def swap(arr, i, j): def sift_down(arr, i, upper): while True: - L, r = i * 2 + 1, i * 2 + 2 - if max(L, r) < upper: - if arr[i] >= max(arr[L], arr[r]): - break - elif arr[L] > arr[r]: - swap(arr, i, L) - i = L - else: - swap(arr, i, r) - i = r - elif L < upper: - if arr[L] > arr[i]: - swap(arr, i, L) - i = L + lef, rig = i * 2 + 1, i * 2 + 2 + + if rig < upper: + if arr[i] >= max(arr[lef], arr[rig]): + return + if arr[lef] > arr[rig]: + swap(arr, i, lef) + i = lef else: - break - elif r < upper: - if arr[r] > arr[i]: - swap(arr, i, r) - i = r + swap(arr, i, rig) + i = rig + + elif lef < upper: + if arr[lef] > arr[i]: + swap(arr, i, lef) + i = lef else: - break + return + else: - break + return def heapsort(arr):