diff --git a/src/sort/quick_sort.py b/src/sort/quick_sort.py new file mode 100644 index 0000000..a76c77c --- /dev/null +++ b/src/sort/quick_sort.py @@ -0,0 +1,22 @@ +import random + +def sort(array): + def get_partition(array, start_idx, end_idx): + pivot_idx = random.randint(start_idx, end_idx) + pivot = array[pivot_idx] + array[pivot_idx], array[end_idx] = array[end_idx], array[pivot_idx] + i = start_idx - 1 + for j in range(start_idx, end_idx): + if array[j] <= pivot: + i += 1 + array[i], array[j] = array[j], array[i] + array[i + 1], array[end_idx] = array[end_idx], array[i + 1] + return i + 1 + + def quick_sort(array, start_idx, end_idx): + if start_idx < end_idx: + partition = get_partition(array, start_idx, end_idx) + quick_sort(array, start_idx, partition - 1) + quick_sort(array, partition + 1, end_idx) + + quick_sort(array, 0, len(array) - 1) diff --git a/tst/sort/test_quick_sort.py b/tst/sort/test_quick_sort.py new file mode 100644 index 0000000..ed4753a --- /dev/null +++ b/tst/sort/test_quick_sort.py @@ -0,0 +1,34 @@ +from src.sort.quick_sort import sort + +class TestQuickSort: + def test_empty_sort(self): + array = [] + sort(array) + assert array == [] + + def test_sorted_and_reverse_inputs(self): + sorted_array = [1, 2, 3, 4, 5] + reverse_array = list(reversed(sorted_array)) + sort(sorted_array) + sort(reverse_array) + assert sorted_array == [1, 2, 3, 4, 5] + assert reverse_array == [1, 2, 3, 4, 5] + + def test_duplicates_and_negatives(self): + array = [3, -1, 0, -1, 5, 3, 2] + sort(array) + assert array == [-1, -1, 0, 2, 3, 3, 5] + + def test_random_pivot_usage(self, monkeypatch): + calls = [] + + def fake_randint(start_idx, end_idx): + calls.append((start_idx, end_idx)) + return start_idx # pick first element to force swaps with pivot + + monkeypatch.setattr("src.sort.quick_sort.random.randint", fake_randint) + array = [10, 5, 8, 3, 2] + sort(array) + assert array == [2, 3, 5, 8, 10] + assert calls[0] == (0, 4) + assert all(start <= end for start, end in calls)