mirror of
https://github.com/TheAlgorithms/Python.git
synced 2026-09-28 13:33:11 +08:00
fix: type recursive mergesort for comparable items (#15406)
Accept any iterable of mutually comparable items and return a new list. Part of #15234
This commit is contained in:
@@ -1,12 +1,23 @@
|
||||
"""A merge sort which accepts an array as input and recursively
|
||||
splits an array in half and sorts and combines them.
|
||||
"""A merge sort which accepts comparable items and recursively
|
||||
splits them in half, then sorts and combines the halves.
|
||||
|
||||
https://en.wikipedia.org/wiki/Merge_sort
|
||||
"""
|
||||
|
||||
"""https://en.wikipedia.org/wiki/Merge_sort """
|
||||
from collections.abc import Iterable
|
||||
from typing import Protocol
|
||||
|
||||
|
||||
def merge(arr: list[int]) -> list[int]:
|
||||
"""Return a sorted array.
|
||||
class Comparable(Protocol):
|
||||
def __lt__(self, other: object, /) -> bool: ...
|
||||
|
||||
|
||||
def merge[T: Comparable](collection: Iterable[T]) -> list[T]:
|
||||
"""Return a new list of ``collection`` sorted in ascending order.
|
||||
|
||||
The input is copied, so the original iterable is left unchanged.
|
||||
Items must be mutually comparable with ``<``.
|
||||
|
||||
>>> merge([10,9,8,7,6,5,4,3,2,1])
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
>>> merge([1,2,3,4,5,6,7,8,9,10])
|
||||
@@ -17,19 +28,30 @@ def merge(arr: list[int]) -> list[int]:
|
||||
[100]
|
||||
>>> merge([])
|
||||
[]
|
||||
>>> merge(["c", "a", "b"])
|
||||
['a', 'b', 'c']
|
||||
>>> merge([2.5, -1, 0.0])
|
||||
[-1, 0.0, 2.5]
|
||||
>>> values = [3, 1, 2]
|
||||
>>> merge(values)
|
||||
[1, 2, 3]
|
||||
>>> values
|
||||
[3, 1, 2]
|
||||
>>> merge(("b", "c", "a"))
|
||||
['a', 'b', 'c']
|
||||
>>> merge([1, "a"])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: '<' not supported between instances of 'int' and 'str'
|
||||
"""
|
||||
arr = list(collection)
|
||||
if len(arr) > 1:
|
||||
middle_length = len(arr) // 2 # Finds the middle of the array
|
||||
left_array = arr[
|
||||
:middle_length
|
||||
] # Creates an array of the elements in the first half.
|
||||
right_array = arr[
|
||||
middle_length:
|
||||
] # Creates an array of the elements in the second half.
|
||||
# Sort each half into a new list, then combine those halves in ``arr``.
|
||||
left_array = merge(arr[:middle_length])
|
||||
right_array = merge(arr[middle_length:])
|
||||
left_size = len(left_array)
|
||||
right_size = len(right_array)
|
||||
merge(left_array) # Starts sorting the left.
|
||||
merge(right_array) # Starts sorting the right
|
||||
left_index = 0 # Left Counter
|
||||
right_index = 0 # Right Counter
|
||||
index = 0 # Position Counter
|
||||
|
||||
@@ -41,6 +41,7 @@ from sorts.pancake_sort import pancake_sort
|
||||
from sorts.patience_sort import patience_sort
|
||||
from sorts.quick_sort import quick_sort
|
||||
from sorts.recursive_insertion_sort import rec_insertion_sort
|
||||
from sorts.recursive_mergesort_array import merge
|
||||
from sorts.reversort import reversort
|
||||
from sorts.selection_sort import selection_sort
|
||||
from sorts.shell_sort import shell_sort
|
||||
@@ -70,6 +71,7 @@ SORTS = (
|
||||
heap_sort,
|
||||
insertion_sort,
|
||||
iter_merge_sort,
|
||||
merge,
|
||||
merge_sort,
|
||||
odd_even_sort,
|
||||
pancake_sort,
|
||||
@@ -140,6 +142,7 @@ def test_rec_insertion_sort(case) -> None:
|
||||
exchange_sort,
|
||||
gnome_sort,
|
||||
insertion_sort,
|
||||
merge,
|
||||
merge_sort,
|
||||
odd_even_sort,
|
||||
pancake_sort,
|
||||
|
||||
Reference in New Issue
Block a user