sorting-suite 1.0.1__py3-none-any.whl

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.
@@ -0,0 +1,33 @@
1
+ from .sorting import (
2
+ swap,
3
+ is_sorted,
4
+ reverse,
5
+ selection_sort,
6
+ shell_sort,
7
+ heap_sort,
8
+ bitonic_sort,
9
+ insertion_sort,
10
+ bogo_sort,
11
+ merge_sort,
12
+ quick_sort,
13
+ bubble_sort,
14
+ bucket_sort,
15
+ comb_sort,
16
+ )
17
+
18
+ __all__ = [
19
+ "swap",
20
+ "is_sorted",
21
+ "reverse",
22
+ "selection_sort",
23
+ "shell_sort",
24
+ "heap_sort",
25
+ "bitonic_sort",
26
+ "insertion_sort",
27
+ "bogo_sort",
28
+ "merge_sort",
29
+ "quick_sort",
30
+ "bubble_sort",
31
+ "bucket_sort",
32
+ "comb_sort"
33
+ ]
@@ -0,0 +1,209 @@
1
+ # Swaps arr[i] and arr[j]
2
+ # Runtime: O(1)
3
+ def swap(arr, i, j):
4
+ temp = arr[i]
5
+ arr[i] = arr[j]
6
+ arr[j] = temp
7
+
8
+ # Checks if a list is sorted
9
+ # Runtime: O(n)
10
+ def is_sorted(arr):
11
+ if not arr:
12
+ return True
13
+ return all(arr[i] <= arr[i + 1] for i in range(len(arr) - 1))
14
+
15
+ # Reverses a list
16
+ # Call on a sorted list to reverse the sorting order
17
+ # Runtime: O(n)
18
+ def reverse(arr):
19
+ return arr[::-1]
20
+
21
+ # Sorts by "bubbling" large elements up into the correct spots
22
+ # Stable
23
+ # Runtime: O(n^2)
24
+ def bubble_sort(arr):
25
+ arr = arr.copy()
26
+ n = len(arr)
27
+ for i in range(n):
28
+ for j in range(0, n - i - 1):
29
+ if arr[j] > arr[j + 1]:
30
+ arr[j], arr[j + 1] = arr[j + 1], arr[j]
31
+ return arr
32
+
33
+ # Sorts by picking pivots, partioning the list into sections, and recursively sorting the parts
34
+ # Runtime: O(n^2)
35
+ def quick_sort(arr):
36
+ if len(arr) <= 1:
37
+ return arr
38
+ pivot = arr[len(arr) // 2]
39
+ left = [x for x in arr if x < pivot]
40
+ mid = [x for x in arr if x == pivot]
41
+ right = [x for x in arr if x > pivot]
42
+ return quick_sort(left) + mid + quick_sort(right)
43
+
44
+ # Sorts by inserting elements into the correct order one at a time
45
+ # Stable
46
+ # Runtime: O(n^2)
47
+ def insertion_sort(arr):
48
+ arr = arr.copy()
49
+ for i in range(1,len(arr)):
50
+ k = arr[i]
51
+ j = i - 1
52
+
53
+ while j >= 0 and arr[j] > k:
54
+ arr[j + 1] = arr[j]
55
+ j -= 1
56
+
57
+ arr[j + 1] = k
58
+ return arr
59
+
60
+ # Sorts by finding the next smallest elements and placing at front
61
+ # Runtime: O(n^2)
62
+ def selection_sort(arr):
63
+ arr = arr.copy()
64
+ n = len(arr)
65
+ for i in range(n):
66
+ min_inx = i
67
+ for j in range(i+1, n):
68
+ if arr[j] < arr[min_inx]:
69
+ min_inx = j
70
+ arr[i], arr[min_inx] = arr[min_inx], arr[i]
71
+ return arr
72
+
73
+ # Sorts by spliting the list in half and recursively sorting
74
+ # Stable
75
+ # Runtime: O(nlog(n))
76
+ def merge_sort(arr):
77
+ if len(arr) <= 1:
78
+ return arr
79
+
80
+ mid = len(arr) // 2
81
+ left = merge_sort(arr[:mid])
82
+ right = merge_sort(arr[mid:])
83
+
84
+ return _merge(left, right)
85
+
86
+ def _merge(left, right):
87
+ i = j = 0
88
+ result = []
89
+
90
+ while i < len(left) and j < len(right):
91
+ if left[i] <= right[j]:
92
+ result.append(left[i])
93
+ i += 1
94
+ else:
95
+ result.append(right[j])
96
+ j += 1
97
+
98
+ return result + left[i:] + right[j:]
99
+
100
+ # Sorts by randomizing the list order and checking if the list is sorted
101
+ # Runtime: O(inf)
102
+ def bogo_sort(arr):
103
+ import random
104
+ arr = arr.copy()
105
+ while not is_sorted(arr):
106
+ random.shuffle(arr)
107
+ return arr
108
+
109
+ # Sorts by sorting into buckets, sorting the buckets, and concatenating
110
+ # Stable
111
+ # Runtime: O(n+k), where k is number of buckets
112
+ def bucket_sort(arr, bucket_size=10):
113
+ if len(arr) == 0:
114
+ return arr
115
+ arr = arr.copy()
116
+ min_val, max_val = min(arr), max(arr)
117
+ bucket_count = (max_val - min_val) // bucket_size + 1
118
+ buckets = [[] for _ in range(bucket_count)]
119
+
120
+ for num in arr:
121
+ index = (num - min_val) // bucket_size
122
+ buckets[index].append(num)
123
+
124
+ sorted_arr = []
125
+ for bucket in buckets:
126
+ sorted_arr.extend(insertion_sort(bucket))
127
+
128
+ return sorted_arr
129
+
130
+ # Sorts by comparing far apart elements and moving them
131
+ # Runtime: O(n^2)
132
+ def shell_sort(arr):
133
+ arr = arr.copy()
134
+ n = len(arr)
135
+ gap = n // 2
136
+ while gap > 0:
137
+ for i in range(gap, n):
138
+ temp = arr[i]
139
+ j = i
140
+ while j >= gap and arr[j - gap] > temp:
141
+ arr[j] = arr[j - gap]
142
+ j -= gap
143
+ arr[j] = temp
144
+ gap //= 2
145
+ return arr
146
+
147
+ # Sorts by taking advantage of binary sequences
148
+ # Runtime: O(log^2(n))
149
+ def bitonic_sort(arr):
150
+ n = len(arr)
151
+ for k in range(2, n+1):
152
+ j = k // 2
153
+ while j > 0:
154
+ for i in range(0, n):
155
+ l = i ^ j
156
+ if l > i:
157
+ if ( ((i&k)==0) and (arr[i] > arr[l]) or ( ( (i&k)!=0) and (arr[i] < arr[l])) ):
158
+ temp = arr[i]
159
+ arr[i] = arr[l]
160
+ arr[l] = temp
161
+ j //= 2
162
+
163
+ # Sorts by using a binary min heap
164
+ # Runtime: O(log(n))
165
+ def heap_sort(arr):
166
+ n = len(arr)
167
+
168
+ for i in range(n//2, -1, -1):
169
+ __heapify(arr, n, i)
170
+
171
+ for i in range(n-1, 0, -1):
172
+ arr[i], arr[0] = arr[0], arr[i]
173
+
174
+ __heapify(arr, i, 0)
175
+
176
+ def __heapify(arr, n, i):
177
+ largest = i
178
+ l = 2 * i + 1
179
+ r = 2 * i + 2
180
+
181
+ if l < n and arr[i] < arr[l]:
182
+ largest = l
183
+
184
+ if r < n and arr[largest] < arr[r]:
185
+ largest = r
186
+
187
+ if largest != i:
188
+ arr[i], arr[largest] = arr[largest], arr[i]
189
+ __heapify(arr, n, largest)
190
+
191
+ # Sorts similarly to bubble sort, but removes turtles
192
+ # Runtime: O(n^2)
193
+ def comb_sort(arr):
194
+ n = len(arr)
195
+ s = 1.3
196
+ gap = n
197
+ sorted = False
198
+
199
+ while not sorted:
200
+ gap = int(gap/s)
201
+ if gap <= 1:
202
+ sorted = True
203
+ gap = 1
204
+
205
+ for i in range(n-gap):
206
+ sm = gap + i
207
+ if arr[i] > arr[sm]:
208
+ arr[i], arr[sm] = arr[sm], arr[i]
209
+ sorted = False
@@ -0,0 +1,67 @@
1
+ from sorting import (
2
+ swap,
3
+ is_sorted,
4
+ reverse,
5
+ selection_sort,
6
+ shell_sort,
7
+ heap_sort,
8
+ insertion_sort,
9
+ bogo_sort,
10
+ merge_sort,
11
+ quick_sort,
12
+ bubble_sort,
13
+ bucket_sort,
14
+ comb_sort
15
+ )
16
+
17
+ def test_sorting_functions():
18
+ test_cases = [
19
+ [],
20
+ [1],
21
+ [2, 1],
22
+ [4, 2, 7, 1, 3],
23
+ [5, 3, 8, 5, 2, 2, 9],
24
+ [1, 2, 3, 4, 5],
25
+ [5, 4, 3, 2, 1],
26
+ [435, 2, 1090, 123, 345, 24, 45, -1204],
27
+ [-90, -1, 0, 32, -4],
28
+ [-1],
29
+ [1, 1, 2, 0, 1, 1, 1, 2, 0, 1]
30
+ ]
31
+
32
+ sorting_functions = [
33
+ selection_sort,
34
+ insertion_sort,
35
+ shell_sort,
36
+ heap_sort,
37
+ merge_sort,
38
+ quick_sort,
39
+ bubble_sort,
40
+ bucket_sort,
41
+ bogo_sort,
42
+ comb_sort
43
+ ]
44
+
45
+ for func in sorting_functions:
46
+ print(f"\nTesting {func.__name__}:")
47
+ for arr in test_cases:
48
+ if func == bogo_sort and len(arr) > 3:
49
+ continue
50
+ result = func(arr)
51
+ print(f"Input: {arr} -> Output: {result} -> Sorted: {is_sorted(result)}")
52
+
53
+ def test_utilities():
54
+ print("\nTesting utility functions:")
55
+
56
+ arr = [4,5,6]
57
+ swap(arr, 0, 2)
58
+ print(f"swap([4,5,6],0,2) -> ({arr})")
59
+
60
+ arr = [1,2,3]
61
+ print(f"reverse([1,2,3]) -> {reverse(arr)}")
62
+ print(f"is_sorted([1,2,3]) -> {is_sorted([1,2,3])}")
63
+ print(f"is_sorted([3,1,2]) -> {is_sorted([3,1,2])}")
64
+
65
+ if __name__ == "__main__":
66
+ test_sorting_functions()
67
+ test_utilities()
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.4
2
+ Name: sorting-suite
3
+ Version: 1.0.1
4
+ Summary: A large suite of numerical sorting algorithms in Python
5
+ Home-page: https://reesefairchild.github.io/sorting-suite
6
+ Author: Reese Fairchild
7
+ Author-email: rfair@uw.edu
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Topic :: Software Development :: Libraries
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Dynamic: license-file
17
+
18
+ **sorting-suite** is a simple Python library providing a comprehensive collection of numerical sorting algorithms, along with helpful utility functions.
19
+ ---
20
+
21
+ ## Sorting Algorithms by Average Runtime
22
+
23
+ **O(n + k)**
24
+ - Bucket Sort
25
+
26
+ **O(log^2 n)**
27
+ - Bitonic Sort (can only be used on lists with size that is multiple of 2)
28
+
29
+ **O(n log n)**
30
+ - Heap Sort
31
+ - Merge Sort
32
+ - Quick Sort
33
+ - Shell Sort
34
+
35
+ **O(n^2)**
36
+ - Bubble Sort
37
+ - Comb Sort
38
+ - Insertion Sort
39
+ - Selection Sort
40
+
41
+ **O(n!)**
42
+ - Bogo Sort (please do not use this one)
43
+
44
+ ---
45
+
46
+ ## Stable Sorts
47
+ - Bucket Sort
48
+ - Bubble Sort
49
+ - Insertion Sort
50
+ - Merge Sort
51
+
52
+ ---
53
+
54
+ ## Utility Functions
55
+
56
+ - **`swap(a, b)`** – Swap two elements.
57
+ - **`is_sorted(arr)`** – Check if an array is sorted.
58
+ - **`reverse(arr)`** – Reverse the elements of a list. Allows above sorting functions
59
+ to sort in descending order, if desired.
60
+
61
+ ---
62
+
63
+ ## Installation
64
+
65
+ ```bash
66
+ pip install sorting-suite
@@ -0,0 +1,8 @@
1
+ sorting_suite/__init__.py,sha256=MuPClu8qmQeu7hk4bDBSnksYsvJOh2oRbovUlbxSNcw,544
2
+ sorting_suite/sorting.py,sha256=zu-Th-xdiyRbwpCLaVGfarYWX3mr6vihB0pA2ros2iQ,5372
3
+ sorting_suite/testing.py,sha256=CdpKSJdJPfkDGjSxfkaPJ-0JA2yRA7piwu-eE9Diki4,1589
4
+ sorting_suite-1.0.1.dist-info/licenses/LICENSE,sha256=VnhoJXSrJmUmafjcQIYfxPneQi-1HtdrB1xqlqSkgfA,1091
5
+ sorting_suite-1.0.1.dist-info/METADATA,sha256=kObyXL5pQ0vRlRxk1Sm62Rj_oKUuylCVnY3_pjq_6zs,1526
6
+ sorting_suite-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ sorting_suite-1.0.1.dist-info/top_level.txt,sha256=szzy3nC-gOlFPZirat3gXpqDWQ1Yhuv9Hh7xf2oISkg,14
8
+ sorting_suite-1.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Reese Fairchild
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ sorting_suite