Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 92 additions & 17 deletions sorts/bubble_sort.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
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
comparable items inside
: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)
Expand All @@ -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")
42 changes: 0 additions & 42 deletions sorts/recursive_bubble_sort.py

This file was deleted.