|
1 | 1 | """ |
2 | | -https://en.wikipedia.org/wiki/Shellsort#Pseudocode |
| 2 | +Shell Sort Algorithm |
| 3 | +-------------------- |
| 4 | +
|
| 5 | +Issue: #13887 |
| 6 | +Implements the Shell Sort algorithm which is a generalization of insertion sort. |
| 7 | +It improves by comparing elements far apart, then reducing the gap between elements |
| 8 | +to be compared until the list is fully sorted. |
| 9 | +
|
| 10 | +Time Complexity: |
| 11 | + Worst case: O(n^2) |
| 12 | + Best case: O(n log n) |
| 13 | + Average: O(n^(3/2)) |
| 14 | +
|
| 15 | +Space Complexity: O(1) |
3 | 16 | """ |
4 | 17 |
|
| 18 | +from __future__ import annotations |
5 | 19 |
|
6 | | -def shell_sort(collection: list[int]) -> list[int]: |
7 | | - """Pure implementation of shell sort algorithm in Python |
8 | | - :param collection: Some mutable ordered collection with heterogeneous |
9 | | - comparable items inside |
10 | | - :return: the same collection ordered by ascending |
11 | 20 |
|
12 | | - >>> shell_sort([0, 5, 3, 2, 2]) |
13 | | - [0, 2, 2, 3, 5] |
| 21 | +def shell_sort(arr: list[int]) -> list[int]: |
| 22 | + """ |
| 23 | + Sorts the given list using Shell Sort and returns the sorted list. |
| 24 | +
|
| 25 | + >>> shell_sort([5, 2, 9, 1]) |
| 26 | + [1, 2, 5, 9] |
14 | 27 | >>> shell_sort([]) |
15 | 28 | [] |
16 | | - >>> shell_sort([-2, -5, -45]) |
17 | | - [-45, -5, -2] |
| 29 | + >>> shell_sort([3]) |
| 30 | + [3] |
| 31 | + >>> shell_sort([1, 2, 3]) |
| 32 | + [1, 2, 3] |
| 33 | + >>> shell_sort([4, 3, 3, 1]) |
| 34 | + [1, 3, 3, 4] |
18 | 35 | """ |
19 | | - # Marcin Ciura's gap sequence |
| 36 | + n = len(arr) |
| 37 | + gap = n // 2 |
20 | 38 |
|
21 | | - gaps = [701, 301, 132, 57, 23, 10, 4, 1] |
22 | | - for gap in gaps: |
23 | | - for i in range(gap, len(collection)): |
24 | | - insert_value = collection[i] |
| 39 | + # Keep reducing the gap until it becomes 0 |
| 40 | + while gap > 0: |
| 41 | + for i in range(gap, n): |
| 42 | + temp = arr[i] |
25 | 43 | j = i |
26 | | - while j >= gap and collection[j - gap] > insert_value: |
27 | | - collection[j] = collection[j - gap] |
| 44 | + while j >= gap and arr[j - gap] > temp: |
| 45 | + arr[j] = arr[j - gap] |
28 | 46 | j -= gap |
29 | | - if j != i: |
30 | | - collection[j] = insert_value |
31 | | - return collection |
32 | | - |
| 47 | + arr[j] = temp |
| 48 | + gap //= 2 |
33 | 49 |
|
34 | | -if __name__ == "__main__": |
35 | | - from doctest import testmod |
| 50 | + return arr |
36 | 51 |
|
37 | | - testmod() |
38 | | - user_input = input("Enter numbers separated by a comma:\n").strip() |
39 | | - unsorted = [int(item) for item in user_input.split(",")] |
40 | | - print(shell_sort(unsorted)) |
|
0 commit comments