|
1 | | -from typing import Any |
2 | 1 |
|
3 | | - |
4 | | -def bubble_sort_iterative(collection: list[Any]) -> list[Any]: |
5 | | - """Pure implementation of bubble sort algorithm in Python |
6 | | -
|
7 | | - :param collection: some mutable ordered collection with heterogeneous |
8 | | - comparable items inside |
9 | | - :return: the same collection ordered by ascending |
10 | | -
|
11 | | - Examples: |
12 | | - >>> bubble_sort_iterative([0, 5, 2, 3, 2]) |
13 | | - [0, 2, 2, 3, 5] |
14 | | - >>> bubble_sort_iterative([]) |
15 | | - [] |
16 | | - >>> bubble_sort_iterative([-2, -45, -5]) |
17 | | - [-45, -5, -2] |
18 | | - >>> bubble_sort_iterative([-23, 0, 6, -4, 34]) |
19 | | - [-23, -4, 0, 6, 34] |
20 | | - >>> bubble_sort_iterative([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2]) |
21 | | - True |
22 | | - >>> bubble_sort_iterative([]) == sorted([]) |
23 | | - True |
24 | | - >>> bubble_sort_iterative([-2, -45, -5]) == sorted([-2, -45, -5]) |
25 | | - True |
26 | | - >>> bubble_sort_iterative([-23, 0, 6, -4, 34]) == sorted([-23, 0, 6, -4, 34]) |
27 | | - True |
28 | | - >>> bubble_sort_iterative(['d', 'a', 'b', 'e']) == sorted(['d', 'a', 'b', 'e']) |
29 | | - True |
30 | | - >>> bubble_sort_iterative(['z', 'a', 'y', 'b', 'x', 'c']) |
31 | | - ['a', 'b', 'c', 'x', 'y', 'z'] |
32 | | - >>> bubble_sort_iterative([1.1, 3.3, 5.5, 7.7, 2.2, 4.4, 6.6]) |
33 | | - [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7] |
34 | | - >>> bubble_sort_iterative([1, 3.3, 5, 7.7, 2, 4.4, 6]) |
35 | | - [1, 2, 3.3, 4.4, 5, 6, 7.7] |
36 | | - >>> import random |
37 | | - >>> collection_arg = random.sample(range(-50, 50), 100) |
38 | | - >>> bubble_sort_iterative(collection_arg) == sorted(collection_arg) |
39 | | - True |
40 | | - >>> import string |
41 | | - >>> collection_arg = random.choices(string.ascii_letters + string.digits, k=100) |
42 | | - >>> bubble_sort_iterative(collection_arg) == sorted(collection_arg) |
43 | | - True |
44 | | - """ |
45 | | - length = len(collection) |
46 | | - for i in reversed(range(length)): |
47 | | - swapped = False |
48 | | - for j in range(i): |
49 | | - if collection[j] > collection[j + 1]: |
50 | | - swapped = True |
51 | | - collection[j], collection[j + 1] = collection[j + 1], collection[j] |
52 | | - if not swapped: |
53 | | - break # Stop iteration if the collection is sorted. |
54 | | - return collection |
55 | | - |
56 | | - |
57 | | -def bubble_sort_recursive(collection: list[Any]) -> list[Any]: |
58 | | - """It is similar iterative bubble sort but recursive. |
59 | | -
|
60 | | - :param collection: mutable ordered sequence of elements |
61 | | - :return: the same list in ascending order |
62 | | -
|
63 | | - Examples: |
64 | | - >>> bubble_sort_recursive([0, 5, 2, 3, 2]) |
65 | | - [0, 2, 2, 3, 5] |
66 | | - >>> bubble_sort_iterative([]) |
67 | | - [] |
68 | | - >>> bubble_sort_recursive([-2, -45, -5]) |
69 | | - [-45, -5, -2] |
70 | | - >>> bubble_sort_recursive([-23, 0, 6, -4, 34]) |
71 | | - [-23, -4, 0, 6, 34] |
72 | | - >>> bubble_sort_recursive([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2]) |
73 | | - True |
74 | | - >>> bubble_sort_recursive([]) == sorted([]) |
75 | | - True |
76 | | - >>> bubble_sort_recursive([-2, -45, -5]) == sorted([-2, -45, -5]) |
77 | | - True |
78 | | - >>> bubble_sort_recursive([-23, 0, 6, -4, 34]) == sorted([-23, 0, 6, -4, 34]) |
79 | | - True |
80 | | - >>> bubble_sort_recursive(['d', 'a', 'b', 'e']) == sorted(['d', 'a', 'b', 'e']) |
81 | | - True |
82 | | - >>> bubble_sort_recursive(['z', 'a', 'y', 'b', 'x', 'c']) |
83 | | - ['a', 'b', 'c', 'x', 'y', 'z'] |
84 | | - >>> bubble_sort_recursive([1.1, 3.3, 5.5, 7.7, 2.2, 4.4, 6.6]) |
85 | | - [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7] |
86 | | - >>> bubble_sort_recursive([1, 3.3, 5, 7.7, 2, 4.4, 6]) |
87 | | - [1, 2, 3.3, 4.4, 5, 6, 7.7] |
88 | | - >>> bubble_sort_recursive(['a', 'Z', 'B', 'C', 'A', 'c']) |
89 | | - ['A', 'B', 'C', 'Z', 'a', 'c'] |
90 | | - >>> import random |
91 | | - >>> collection_arg = random.sample(range(-50, 50), 100) |
92 | | - >>> bubble_sort_recursive(collection_arg) == sorted(collection_arg) |
93 | | - True |
94 | | - >>> import string |
95 | | - >>> collection_arg = random.choices(string.ascii_letters + string.digits, k=100) |
96 | | - >>> bubble_sort_recursive(collection_arg) == sorted(collection_arg) |
97 | | - True |
98 | | - """ |
99 | | - length = len(collection) |
100 | | - swapped = False |
101 | | - for i in range(length - 1): |
102 | | - if collection[i] > collection[i + 1]: |
103 | | - collection[i], collection[i + 1] = collection[i + 1], collection[i] |
104 | | - swapped = True |
105 | | - |
106 | | - return collection if not swapped else bubble_sort_recursive(collection) |
107 | | - |
108 | | - |
109 | | -if __name__ == "__main__": |
110 | | - import doctest |
111 | | - from random import sample |
112 | | - from timeit import timeit |
113 | | - |
114 | | - doctest.testmod() |
115 | | - |
116 | | - # Benchmark: Iterative seems slightly faster than recursive. |
117 | | - num_runs = 10_000 |
118 | | - unsorted = sample(range(-50, 50), 100) |
119 | | - timer_iterative = timeit( |
120 | | - "bubble_sort_iterative(unsorted[:])", globals=globals(), number=num_runs |
121 | | - ) |
122 | | - print("\nIterative bubble sort:") |
123 | | - print(*bubble_sort_iterative(unsorted), sep=",") |
124 | | - print(f"Processing time (iterative): {timer_iterative:.5f}s for {num_runs:,} runs") |
125 | | - |
126 | | - unsorted = sample(range(-50, 50), 100) |
127 | | - timer_recursive = timeit( |
128 | | - "bubble_sort_recursive(unsorted[:])", globals=globals(), number=num_runs |
129 | | - ) |
130 | | - print("\nRecursive bubble sort:") |
131 | | - print(*bubble_sort_recursive(unsorted), sep=",") |
132 | | - print(f"Processing time (recursive): {timer_recursive:.5f}s for {num_runs:,} runs") |
0 commit comments