Skip to content

Commit 800ae08

Browse files
committed
Adding Comb Sort algorithm
1 parent f9e10ca commit 800ae08

File tree

7 files changed

+121
-7
lines changed

7 files changed

+121
-7
lines changed

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
- repo: https://github.com/pre-commit/pre-commit-hooks.git
2-
sha: v0.7.0
2+
sha: v0.8.0
33
hooks:
44
- id: trailing-whitespace
55
args: ['--no-markdown-linebreak-ext']

README.md

+26-2
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@ $ pip install py-algorithms
3232
- Max PQ
3333
- Suffix Array
3434

35-
^ Search
35+
^ Search Algorithms
3636
- Binary Search
3737

38-
^ Sorting
38+
^ Sort Algorithms
3939
- Shell Sort (Shell method)
4040
- Heap Sort (Fibonacci heap)
4141
- Merge Sort
42+
- Comb Sort
4243
- Bubble Sort
4344
- Selection Sort
4445

@@ -98,6 +99,29 @@ sorting_algorithm(xs)
9899
#=> [-1, 0, 4, 5, 6, 7, 8, 9, 12]
99100
```
100101

102+
#### *Comb Sort (https://en.wikipedia.org/wiki/Comb_sort)
103+
104+
Comb sort is a relatively simple sorting algorithm originally designed by
105+
Włodzimierz Dobosiewicz in 1980. Later it was rediscovered by Stephen Lacey and Richard Box in 1991.
106+
Comb sort improves on bubble sort. The basic idea is to eliminate turtles,
107+
or small values near the end of the list, since in a bubble sort these slow the sorting down tremendously.
108+
Rabbits, large values around the beginning of the list, do not pose a problem in bubble sort.
109+
110+
Worst case: О(n^2)
111+
Best case: О(n log n)
112+
Average: О(n^2)
113+
Worst case space: O(1)
114+
115+
```python
116+
from py_algorithms.sort import new_comb_sort
117+
118+
xs = [0, 6, 7, 8, 9, 4, 5, 12, -1]
119+
sorting_algorithm = new_comb_sort()
120+
sorting_algorithm(xs)
121+
122+
#=> [-1, 0, 4, 5, 6, 7, 8, 9, 12]
123+
```
124+
101125
#### *Selection Sort (https://en.wikipedia.org/wiki/Selection_sort)
102126

103127
In computer science, selection sort is a sorting algorithm,

py_algorithms/sort/__init__.py

+21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import List
33

44
from ._bubble_sort import BubbleSort
5+
from ._comb_sort import CombSort
56
from ._heap_sort import FibonacciHeapSort
67
from ._merge_sort import RecursiveMergeSort
78
from ._selection_sort import SelectionSort
@@ -12,6 +13,9 @@
1213
'new_bubble_sort',
1314
'new_merge_sort',
1415
'new_selection_sort',
16+
'new_heap_sort',
17+
'new_shell_sort',
18+
'new_comb_sort',
1519
'Sort'
1620
]
1721

@@ -91,3 +95,20 @@ def new_shell_sort() -> Callable[[List[int]], List[int]]:
9195
"""
9296

9397
return lambda xs: ShellSort().sort(xs)
98+
99+
100+
def new_comb_sort() -> Callable[[List[int]], List[int]]:
101+
"""
102+
- Comb Sort algorithm (Improved on Bubble Sort).
103+
Factory method to return sort functor.
104+
105+
>>> from py_algorithms.sort import new_comb_sort
106+
>>>
107+
>>> xs = [0, 6, 7, 8, 9, 4, 5, 12, -1]
108+
>>> sorting_algorithm = new_comb_sort()
109+
>>> sorting_algorithm(xs) #=> [-1, 0, 4, 5, 6, 7, 8, 9, 12]
110+
111+
:return: a function1 interface to apply
112+
"""
113+
114+
return lambda xs: CombSort().sort(xs)

py_algorithms/sort/_comb_sort.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import math
2+
from typing import List
3+
4+
from ..utils import test_iterable
5+
from ..utils import three_way_cmp
6+
from .sort import Sort
7+
8+
9+
class CombSort(Sort):
10+
_SHRINK = 1.3
11+
"""
12+
Worst-case: О(n^2)
13+
Best-case: O(n log n)
14+
Space: О(1)
15+
Stability: true
16+
"""
17+
18+
def sort(self, xs: List[int]) -> List[int]:
19+
test_iterable(xs)
20+
21+
gap = len(xs)
22+
in_order = False
23+
24+
while not in_order:
25+
gap = math.floor(gap / self._SHRINK) # simply gap * 10 // 13
26+
27+
if gap < 1:
28+
gap = 1
29+
30+
swapped = False
31+
for i in range(len(xs) - gap):
32+
if three_way_cmp(xs[i], xs[i + gap]) == 1:
33+
xs[i], xs[i + gap] = xs[i + gap], xs[i]
34+
swapped = True
35+
if not swapped and gap == 1:
36+
in_order = True
37+
38+
return xs

setup.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
'fibonacci priority queue', 'max priority queue', 'min priority queue',
2424
'dynamic connectivity', 'union find', 'quick union', 'weighted quick union',
2525
'weighted quick union with path compression', 'fibonacci heap sort', 'heapsort',
26-
'heap sort', 'shell-sort', 'shell sort'],
26+
'heap sort', 'shell-sort', 'shell sort', 'comb sort', 'comb-sort'],
2727
description="Library of Algorithms, Data Structures, variety of solutions to common "
28-
"CS problems",
29-
long_description="Algorithms and Data Structures implemented using awesome Python.",
28+
"CS problems.",
29+
long_description="Library of Algorithms, Data Structures, variety of solutions to common "
30+
"CS problems. Algorithms and Data Structures implemented using pure awesome "
31+
"Python.",
3032
license="MIT",
3133
url='https://github.com/rlishtaba/py-algorithms',
3234
scripts=[],
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import Callable
2+
from typing import List
3+
4+
import pytest
5+
6+
from py_algorithms.sort import new_comb_sort
7+
from tests.conftest import large_xs
8+
from tests.conftest import xs
9+
10+
11+
@pytest.fixture
12+
def new_sorting_algorithm() -> Callable[[List[int]], List[int]]:
13+
return new_comb_sort()
14+
15+
16+
class TestCombSort:
17+
def test_sorting_algorithm(self):
18+
f = new_sorting_algorithm()
19+
assert sorted(xs()) == f(xs())
20+
21+
def test_sorting_algorithm_on_large_xs(self):
22+
f = new_sorting_algorithm()
23+
assert sorted(large_xs()) == f(large_xs())
24+
25+
def test_non_iterable_xs(self):
26+
f = new_sorting_algorithm()
27+
for x in (None, 1, ''):
28+
with pytest.raises(RuntimeError):
29+
f(x)

tests/py_algorithms/sort/shell_sort_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def new_sorting_algorithm() -> Callable[[List[int]], List[int]]:
1313
return new_shell_sort()
1414

1515

16-
class TestSelectionSort:
16+
class TestShellSort:
1717
def test_sorting_algorithm(self):
1818
f = new_sorting_algorithm()
1919
assert sorted(xs()) == f(xs())

0 commit comments

Comments
 (0)