Skip to content

Commit bf644b2

Browse files
committed
sorts: make recursive_insertion_sort generic over Comparable items
Part of #15234 - switch rec_insertion_sort/insert_next to the Comparable/TypeVar-bound MutableSequence[T] pattern (in-place sorts bucket) per the convention discussed on #15234 - make rec_insertion_sort return the sorted collection and give n a default of len(collection), so it can be called with a single argument like the other sorts in the shared test battery - add a string doctest - register rec_insertion_sort in tests/test_sorts.py's shared SORTS battery and the non-comparable-items rejection test
1 parent 7b5e704 commit bf644b2

2 files changed

Lines changed: 36 additions & 11 deletions

File tree

sorts/recursive_insertion_sort.py

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,61 @@
44

55
from __future__ import annotations
66

7+
from collections.abc import MutableSequence
8+
from typing import Any, Protocol, TypeVar
79

8-
def rec_insertion_sort(collection: list, n: int) -> None:
10+
11+
class Comparable(Protocol):
12+
def __lt__(self, other: Any, /) -> bool: ...
13+
14+
15+
T = TypeVar("T", bound=Comparable)
16+
17+
18+
def rec_insertion_sort[T: Comparable](
19+
collection: MutableSequence[T], n: int | None = None
20+
) -> MutableSequence[T]:
921
"""
10-
Given a collection of numbers and its length, sorts the collections
11-
in ascending order
22+
Given a collection of comparable elements, sorts the collection in place
23+
in ascending order and returns it.
1224
1325
:param collection: A mutable collection of comparable elements
14-
:param n: The length of collections
26+
:param n: The number of leading elements still to be placed. Defaults to
27+
the full length of ``collection`` so the function can be called with
28+
a single argument.
29+
:return: the same collection ordered by ascending
1530
1631
>>> col = [1, 2, 1]
17-
>>> rec_insertion_sort(col, len(col))
32+
>>> rec_insertion_sort(col)
33+
[1, 1, 2]
1834
>>> col
1935
[1, 1, 2]
2036
2137
>>> col = [2, 1, 0, -1, -2]
2238
>>> rec_insertion_sort(col, len(col))
23-
>>> col
2439
[-2, -1, 0, 1, 2]
2540
2641
>>> col = [1]
27-
>>> rec_insertion_sort(col, len(col))
28-
>>> col
42+
>>> rec_insertion_sort(col)
2943
[1]
44+
45+
>>> col = ['d', 'a', 'b', 'e', 'c']
46+
>>> rec_insertion_sort(col) == sorted(col)
47+
True
3048
"""
49+
if n is None:
50+
n = len(collection)
51+
3152
# Checks if the entire collection has been sorted
3253
if len(collection) <= 1 or n <= 1:
33-
return
54+
return collection
3455

3556
insert_next(collection, n - 1)
3657
rec_insertion_sort(collection, n - 1)
58+
return collection
3759

3860

39-
def insert_next(collection: list, index: int) -> None:
61+
def insert_next[T: Comparable](collection: MutableSequence[T], index: int) -> None:
4062
"""
4163
Inserts the '(index-1)th' element into place
4264
@@ -71,5 +93,5 @@ def insert_next(collection: list, index: int) -> None:
7193
if __name__ == "__main__":
7294
numbers = input("Enter integers separated by spaces: ")
7395
number_list: list[int] = [int(num) for num in numbers.split()]
74-
rec_insertion_sort(number_list, len(number_list))
96+
rec_insertion_sort(number_list)
7597
print(number_list)

tests/test_sorts.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from sorts.odd_even_sort import odd_even_sort
3636
from sorts.patience_sort import patience_sort
3737
from sorts.quick_sort import quick_sort
38+
from sorts.recursive_insertion_sort import rec_insertion_sort
3839
from sorts.selection_sort import selection_sort
3940
from sorts.shell_sort import shell_sort
4041
from sorts.stooge_sort import stooge_sort
@@ -66,6 +67,7 @@ def test_heap_sort() -> None:
6667
odd_even_sort,
6768
patience_sort,
6869
quick_sort,
70+
rec_insertion_sort,
6971
selection_sort,
7072
shell_sort,
7173
stooge_sort,
@@ -121,6 +123,7 @@ def test_sort_matches_builtin(sort, case) -> None:
121123
gnome_sort,
122124
insertion_sort,
123125
merge_sort,
126+
rec_insertion_sort,
124127
selection_sort,
125128
],
126129
ids=lambda f: f.__name__,

0 commit comments

Comments
 (0)