algokit-py 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {algokit_py-0.3.0 → algokit_py-0.4.0}/PKG-INFO +1 -1
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py/__init__.py +2 -2
- algokit_py-0.4.0/algokit_py/sort/__init__.py +5 -0
- algokit_py-0.4.0/algokit_py/sort/quick.py +88 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py.egg-info/PKG-INFO +1 -1
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py.egg-info/SOURCES.txt +3 -1
- {algokit_py-0.3.0 → algokit_py-0.4.0}/pyproject.toml +1 -1
- algokit_py-0.4.0/tests/test_quick.py +37 -0
- algokit_py-0.3.0/algokit_py/sort/__init__.py +0 -4
- {algokit_py-0.3.0 → algokit_py-0.4.0}/README.md +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py/search/__init__.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py/search/binary.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py/search/linear.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py/sort/insertion.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py/sort/merge.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py.egg-info/dependency_links.txt +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/algokit_py.egg-info/top_level.txt +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/setup.cfg +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/tests/test_binary.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/tests/test_insertion.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/tests/test_linear.py +0 -0
- {algokit_py-0.3.0 → algokit_py-0.4.0}/tests/test_merge.py +0 -0
|
@@ -3,6 +3,6 @@ algokit_py - A minimal Python algorithms library
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from algokit_py.search import binary_search, linear_search
|
|
6
|
-
from algokit_py.sort import insertion_sort, merge_sort
|
|
6
|
+
from algokit_py.sort import insertion_sort, merge_sort,quick_sort
|
|
7
7
|
|
|
8
|
-
__all__ = ["binary_search", "linear_search","insertion_sort","merge_sort"]
|
|
8
|
+
__all__ = ["binary_search", "linear_search","insertion_sort","merge_sort","quick_sort"]
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from typing import TypeVar, MutableSequence
|
|
2
|
+
|
|
3
|
+
T = TypeVar("T")
|
|
4
|
+
|
|
5
|
+
# We use mutable sequence because we need to modify the list in place
|
|
6
|
+
def quick_sort(sequence: MutableSequence[T]):
|
|
7
|
+
"""
|
|
8
|
+
In-place Quick Sort implementation using divide-and-conquer.
|
|
9
|
+
|
|
10
|
+
This function sorts the given sequence in place.
|
|
11
|
+
|
|
12
|
+
Average Time Complexity: O(n log n)
|
|
13
|
+
Worst Case Time Complexity: O(n^2)
|
|
14
|
+
Space Complexity: O(log n) due to recursion
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
if len(sequence) <= 1:
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
_quick_sort(sequence, 0, len(sequence) - 1)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _partition(sequence,low,high)-> int:
|
|
24
|
+
"""
|
|
25
|
+
Partition the sequence using the Lomuto partition scheme.
|
|
26
|
+
|
|
27
|
+
This function selects the last element as the pivot and rearranges
|
|
28
|
+
the sequence in place so that:
|
|
29
|
+
- all elements less than or equal to the pivot are placed to its left
|
|
30
|
+
- all elements greater than the pivot are placed to its right
|
|
31
|
+
|
|
32
|
+
The pivot is moved to its final correct position, and its index
|
|
33
|
+
is returned.
|
|
34
|
+
|
|
35
|
+
:param sequence: Mutable sequence to be partitioned
|
|
36
|
+
:param low: Starting index of the subarray
|
|
37
|
+
:param high: Ending index of the subarray (pivot index)
|
|
38
|
+
:return: Final index position of the pivot
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
pivot = sequence[high]
|
|
42
|
+
|
|
43
|
+
# at the start, no elements <= pivot.
|
|
44
|
+
i = low - 1
|
|
45
|
+
|
|
46
|
+
# we need to arrange the sub array into these segments: [≤ pivot | > pivot | pivot]
|
|
47
|
+
for j in range(low,high): # up to high - 1
|
|
48
|
+
if sequence[j] <= pivot:
|
|
49
|
+
i += 1
|
|
50
|
+
sequence[i],sequence[j] = sequence[j],sequence[i]
|
|
51
|
+
|
|
52
|
+
# place pivot in its final position
|
|
53
|
+
sequence[i+1],sequence[high] = sequence[high], sequence[i+1]
|
|
54
|
+
|
|
55
|
+
return i + 1
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _quick_sort(sequence,low,high):
|
|
59
|
+
"""
|
|
60
|
+
Recursively sort a subarray of the sequence in place using Quick Sort.
|
|
61
|
+
|
|
62
|
+
This helper function sorts the elements in the index range
|
|
63
|
+
sequence[low : high + 1] using the divide-and-conquer approach.
|
|
64
|
+
It assumes that the partitioning logic correctly places the pivot
|
|
65
|
+
in its final position and recursively sorts the left and right
|
|
66
|
+
subarrays around the pivot.
|
|
67
|
+
|
|
68
|
+
Base case:
|
|
69
|
+
- If low >= high, the subarray has zero or one element and is already sorted.
|
|
70
|
+
|
|
71
|
+
:param sequence: Mutable sequence to be sorted in place
|
|
72
|
+
:param low: Starting index of the subarray
|
|
73
|
+
:param high: Ending index of the subarray
|
|
74
|
+
:return: None
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
# If the subarray has 0 or 1 element
|
|
78
|
+
# That means it is already sorted
|
|
79
|
+
# This happens when:low >= high
|
|
80
|
+
|
|
81
|
+
if low >= high:
|
|
82
|
+
return # No return: because we do this in place
|
|
83
|
+
|
|
84
|
+
p = _partition(sequence,low,high)
|
|
85
|
+
|
|
86
|
+
_quick_sort(sequence,low,p-1)
|
|
87
|
+
_quick_sort(sequence,p+1,high)
|
|
88
|
+
|
|
@@ -11,7 +11,9 @@ algokit_py/search/linear.py
|
|
|
11
11
|
algokit_py/sort/__init__.py
|
|
12
12
|
algokit_py/sort/insertion.py
|
|
13
13
|
algokit_py/sort/merge.py
|
|
14
|
+
algokit_py/sort/quick.py
|
|
14
15
|
tests/test_binary.py
|
|
15
16
|
tests/test_insertion.py
|
|
16
17
|
tests/test_linear.py
|
|
17
|
-
tests/test_merge.py
|
|
18
|
+
tests/test_merge.py
|
|
19
|
+
tests/test_quick.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "algokit-py"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "A minimal Python algorithms library with clean implementations of search algorithms and sort algorithms"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from algokit_py.sort import quick_sort
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_quick_sort_basic():
|
|
5
|
+
data = [3, 1, 2]
|
|
6
|
+
quick_sort(data)
|
|
7
|
+
assert data == [1, 2, 3]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_quick_sort_already_sorted():
|
|
11
|
+
data = [1, 2, 3, 4]
|
|
12
|
+
quick_sort(data)
|
|
13
|
+
assert data == [1, 2, 3, 4]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_quick_sort_reverse():
|
|
17
|
+
data = [4, 3, 2, 1]
|
|
18
|
+
quick_sort(data)
|
|
19
|
+
assert data == [1, 2, 3, 4]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_quick_sort_duplicates():
|
|
23
|
+
data = [3, 1, 2, 1]
|
|
24
|
+
quick_sort(data)
|
|
25
|
+
assert data == [1, 1, 2, 3]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_quick_sort_single_element():
|
|
29
|
+
data = [5]
|
|
30
|
+
quick_sort(data)
|
|
31
|
+
assert data == [5]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_quick_sort_empty():
|
|
35
|
+
data = []
|
|
36
|
+
quick_sort(data)
|
|
37
|
+
assert data == []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|