mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
Consolidate bubble sort iterative and recursive (#10651)
* Consolidate bubble sort iterative and recursive * Update sorts/bubble_sort.py Co-authored-by: Christian Clauss <cclauss@me.com> * Refactor bubble sort func signature, doctest, timer * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update bubble_sort.py --------- Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
34f48b684b
commit
9875f374f4
|
@ -1,7 +1,7 @@
|
|||
from typing import Any
|
||||
|
||||
|
||||
def bubble_sort(collection: list[Any]) -> list[Any]:
|
||||
def bubble_sort_iterative(collection: list[Any]) -> list[Any]:
|
||||
"""Pure implementation of bubble sort algorithm in Python
|
||||
|
||||
:param collection: some mutable ordered collection with heterogeneous
|
||||
|
@ -9,25 +9,37 @@ def bubble_sort(collection: list[Any]) -> list[Any]:
|
|||
:return: the same collection ordered by ascending
|
||||
|
||||
Examples:
|
||||
>>> bubble_sort([0, 5, 2, 3, 2])
|
||||
>>> bubble_sort_iterative([0, 5, 2, 3, 2])
|
||||
[0, 2, 2, 3, 5]
|
||||
>>> bubble_sort([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2])
|
||||
>>> bubble_sort_iterative([])
|
||||
[]
|
||||
>>> bubble_sort_iterative([-2, -45, -5])
|
||||
[-45, -5, -2]
|
||||
>>> bubble_sort_iterative([-23, 0, 6, -4, 34])
|
||||
[-23, -4, 0, 6, 34]
|
||||
>>> bubble_sort_iterative([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2])
|
||||
True
|
||||
>>> bubble_sort([]) == sorted([])
|
||||
>>> bubble_sort_iterative([]) == sorted([])
|
||||
True
|
||||
>>> bubble_sort([-2, -45, -5]) == sorted([-2, -45, -5])
|
||||
>>> bubble_sort_iterative([-2, -45, -5]) == sorted([-2, -45, -5])
|
||||
True
|
||||
>>> bubble_sort([-23, 0, 6, -4, 34]) == sorted([-23, 0, 6, -4, 34])
|
||||
>>> bubble_sort_iterative([-23, 0, 6, -4, 34]) == sorted([-23, 0, 6, -4, 34])
|
||||
True
|
||||
>>> bubble_sort(['d', 'a', 'b', 'e', 'c']) == sorted(['d', 'a', 'b', 'e', 'c'])
|
||||
>>> bubble_sort_iterative(['d', 'a', 'b', 'e']) == sorted(['d', 'a', 'b', 'e'])
|
||||
True
|
||||
>>> bubble_sort_iterative(['z', 'a', 'y', 'b', 'x', 'c'])
|
||||
['a', 'b', 'c', 'x', 'y', 'z']
|
||||
>>> bubble_sort_iterative([1.1, 3.3, 5.5, 7.7, 2.2, 4.4, 6.6])
|
||||
[1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7]
|
||||
>>> bubble_sort_iterative([1, 3.3, 5, 7.7, 2, 4.4, 6])
|
||||
[1, 2, 3.3, 4.4, 5, 6, 7.7]
|
||||
>>> import random
|
||||
>>> collection = random.sample(range(-50, 50), 100)
|
||||
>>> bubble_sort(collection) == sorted(collection)
|
||||
>>> collection_arg = random.sample(range(-50, 50), 100)
|
||||
>>> bubble_sort_iterative(collection_arg) == sorted(collection_arg)
|
||||
True
|
||||
>>> import string
|
||||
>>> collection = random.choices(string.ascii_letters + string.digits, k=100)
|
||||
>>> bubble_sort(collection) == sorted(collection)
|
||||
>>> collection_arg = random.choices(string.ascii_letters + string.digits, k=100)
|
||||
>>> bubble_sort_iterative(collection_arg) == sorted(collection_arg)
|
||||
True
|
||||
"""
|
||||
length = len(collection)
|
||||
|
@ -42,14 +54,77 @@ def bubble_sort(collection: list[Any]) -> list[Any]:
|
|||
return collection
|
||||
|
||||
|
||||
def bubble_sort_recursive(collection: list[Any]) -> list[Any]:
|
||||
"""It is similar iterative bubble sort but recursive.
|
||||
|
||||
:param collection: mutable ordered sequence of elements
|
||||
:return: the same list in ascending order
|
||||
|
||||
Examples:
|
||||
>>> bubble_sort_recursive([0, 5, 2, 3, 2])
|
||||
[0, 2, 2, 3, 5]
|
||||
>>> bubble_sort_iterative([])
|
||||
[]
|
||||
>>> bubble_sort_recursive([-2, -45, -5])
|
||||
[-45, -5, -2]
|
||||
>>> bubble_sort_recursive([-23, 0, 6, -4, 34])
|
||||
[-23, -4, 0, 6, 34]
|
||||
>>> bubble_sort_recursive([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2])
|
||||
True
|
||||
>>> bubble_sort_recursive([]) == sorted([])
|
||||
True
|
||||
>>> bubble_sort_recursive([-2, -45, -5]) == sorted([-2, -45, -5])
|
||||
True
|
||||
>>> bubble_sort_recursive([-23, 0, 6, -4, 34]) == sorted([-23, 0, 6, -4, 34])
|
||||
True
|
||||
>>> bubble_sort_recursive(['d', 'a', 'b', 'e']) == sorted(['d', 'a', 'b', 'e'])
|
||||
True
|
||||
>>> bubble_sort_recursive(['z', 'a', 'y', 'b', 'x', 'c'])
|
||||
['a', 'b', 'c', 'x', 'y', 'z']
|
||||
>>> bubble_sort_recursive([1.1, 3.3, 5.5, 7.7, 2.2, 4.4, 6.6])
|
||||
[1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7]
|
||||
>>> bubble_sort_recursive([1, 3.3, 5, 7.7, 2, 4.4, 6])
|
||||
[1, 2, 3.3, 4.4, 5, 6, 7.7]
|
||||
>>> import random
|
||||
>>> collection_arg = random.sample(range(-50, 50), 100)
|
||||
>>> bubble_sort_recursive(collection_arg) == sorted(collection_arg)
|
||||
True
|
||||
>>> import string
|
||||
>>> collection_arg = random.choices(string.ascii_letters + string.digits, k=100)
|
||||
>>> bubble_sort_recursive(collection_arg) == sorted(collection_arg)
|
||||
True
|
||||
"""
|
||||
length = len(collection)
|
||||
swapped = False
|
||||
for i in range(length - 1):
|
||||
if collection[i] > collection[i + 1]:
|
||||
collection[i], collection[i + 1] = collection[i + 1], collection[i]
|
||||
swapped = True
|
||||
|
||||
return collection if not swapped else bubble_sort_recursive(collection)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
import time
|
||||
from random import sample
|
||||
from timeit import timeit
|
||||
|
||||
doctest.testmod()
|
||||
|
||||
user_input = input("Enter numbers separated by a comma:").strip()
|
||||
unsorted = [int(item) for item in user_input.split(",")]
|
||||
start = time.process_time()
|
||||
print(*bubble_sort(unsorted), sep=",")
|
||||
print(f"Processing time: {(time.process_time() - start)%1e9 + 7}")
|
||||
# Benchmark: Iterative seems slightly faster than recursive.
|
||||
num_runs = 10_000
|
||||
unsorted = sample(range(-50, 50), 100)
|
||||
timer_iterative = timeit(
|
||||
"bubble_sort_iterative(unsorted[:])", globals=globals(), number=num_runs
|
||||
)
|
||||
print("\nIterative bubble sort:")
|
||||
print(*bubble_sort_iterative(unsorted), sep=",")
|
||||
print(f"Processing time (iterative): {timer_iterative:.5f}s for {num_runs:,} runs")
|
||||
|
||||
unsorted = sample(range(-50, 50), 100)
|
||||
timer_recursive = timeit(
|
||||
"bubble_sort_recursive(unsorted[:])", globals=globals(), number=num_runs
|
||||
)
|
||||
print("\nRecursive bubble sort:")
|
||||
print(*bubble_sort_recursive(unsorted), sep=",")
|
||||
print(f"Processing time (recursive): {timer_recursive:.5f}s for {num_runs:,} runs")
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
def bubble_sort(list_data: list, length: int = 0) -> list:
|
||||
"""
|
||||
It is similar is bubble sort but recursive.
|
||||
:param list_data: mutable ordered sequence of elements
|
||||
:param length: length of list data
|
||||
:return: the same list in ascending order
|
||||
|
||||
>>> bubble_sort([0, 5, 2, 3, 2], 5)
|
||||
[0, 2, 2, 3, 5]
|
||||
|
||||
>>> bubble_sort([], 0)
|
||||
[]
|
||||
|
||||
>>> bubble_sort([-2, -45, -5], 3)
|
||||
[-45, -5, -2]
|
||||
|
||||
>>> bubble_sort([-23, 0, 6, -4, 34], 5)
|
||||
[-23, -4, 0, 6, 34]
|
||||
|
||||
>>> bubble_sort([-23, 0, 6, -4, 34], 5) == sorted([-23, 0, 6, -4, 34])
|
||||
True
|
||||
|
||||
>>> bubble_sort(['z','a','y','b','x','c'], 6)
|
||||
['a', 'b', 'c', 'x', 'y', 'z']
|
||||
|
||||
>>> bubble_sort([1.1, 3.3, 5.5, 7.7, 2.2, 4.4, 6.6])
|
||||
[1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7]
|
||||
"""
|
||||
length = length or len(list_data)
|
||||
swapped = False
|
||||
for i in range(length - 1):
|
||||
if list_data[i] > list_data[i + 1]:
|
||||
list_data[i], list_data[i + 1] = list_data[i + 1], list_data[i]
|
||||
swapped = True
|
||||
|
||||
return list_data if not swapped else bubble_sort(list_data, length - 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
Loading…
Reference in New Issue
Block a user