Skip to content

Commit 80c14f5

Browse files
nlw0LilithHafner
andauthored
Add the CombSort algorithm (#54)
Co-authored-by: Lilith Hafner <[email protected]>
1 parent a17c80c commit 80c14f5

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/SortingAlgorithms.jl

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,43 @@ using Base.Order
99
import Base.Sort: sort!
1010
import DataStructures: heapify!, percolate_down!
1111

12-
export HeapSort, TimSort, RadixSort
12+
export HeapSort, TimSort, RadixSort, CombSort
1313

1414
struct HeapSortAlg <: Algorithm end
1515
struct TimSortAlg <: Algorithm end
1616
struct RadixSortAlg <: Algorithm end
17+
struct CombSortAlg <: Algorithm end
1718

1819
const HeapSort = HeapSortAlg()
1920
const TimSort = TimSortAlg()
2021
const RadixSort = RadixSortAlg()
2122

23+
"""
24+
CombSort
25+
26+
Indicates that a sorting function should use the comb sort
27+
algorithm. Comb sort traverses the collection multiple times
28+
ordering pairs of elements with a given interval between them.
29+
The interval decreases exponentially until it becomes 1, then
30+
it switches to insertion sort on the whole input.
31+
32+
Characteristics:
33+
- *not stable* does not preserve the ordering of elements which
34+
compare equal (e.g. "a" and "A" in a sort of letters which
35+
ignores case).
36+
- *in-place* in memory.
37+
- *parallelizable* suitable for vectorization with SIMD instructions
38+
because it performs many independent comparisons.
39+
- *pathological inputs* such as `repeat(1:5.0, 4^8)` can make this algorithm perform very poorly.
40+
- *`n log n` average runtime* measured for random inputs of length up to 100 million, but theoretical runtime of `Θ(n^2)` for extremely long inputs.
41+
42+
## References
43+
- Dobosiewicz, Wlodzimierz, (1980). "An efficient variation of bubble sort", Information Processing Letters, 11(1), pp. 5-6, https://doi.org/10.1016/0020-0190(80)90022-8.
44+
- Werneck, N. L., (2020). "ChipSort: a SIMD and cache-aware sorting module. JuliaCon Proceedings, 1(1), 12, https://doi.org/10.21105/jcon.00012
45+
- H. Inoue, T. Moriyama, H. Komatsu and T. Nakatani, "AA-Sort: A New Parallel Sorting Algorithm for Multi-Core SIMD Processors," 16th International Conference on Parallel Architecture and Compilation Techniques (PACT 2007), 2007, pp. 189-198, doi: 10.1109/PACT.2007.4336211.
46+
"""
47+
const CombSort = CombSortAlg()
48+
2249

2350
## Heap sort
2451

@@ -578,4 +605,18 @@ function sort!(v::AbstractVector, lo::Int, hi::Int, ::TimSortAlg, o::Ordering)
578605
return v
579606
end
580607

608+
function sort!(v::AbstractVector, lo::Int, hi::Int, ::CombSortAlg, o::Ordering)
609+
interval = (3 * (hi-lo+1)) >> 2
610+
611+
while interval > 1
612+
@inbounds for j in lo:hi-interval
613+
a, b = v[j], v[j+interval]
614+
v[j], v[j+interval] = lt(o, b, a) ? (b, a) : (a, b)
615+
end
616+
interval = (3 * interval) >> 2
617+
end
618+
619+
return sort!(v, lo, hi, InsertionSort, o)
620+
end
621+
581622
end # module

test/runtests.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using Random
55

66
a = rand(1:10000, 1000)
77

8-
for alg in [TimSort, HeapSort, RadixSort]
8+
for alg in [TimSort, HeapSort, RadixSort, CombSort]
99
b = sort(a, alg=alg)
1010
@test issorted(b)
1111
ix = sortperm(a, alg=alg)
@@ -85,7 +85,7 @@ for n in [0:10..., 100, 101, 1000, 1001]
8585
end
8686

8787
# unstable algorithms
88-
for alg in [HeapSort]
88+
for alg in [HeapSort, CombSort]
8989
p = sortperm(v, alg=alg, order=ord)
9090
@test isperm(p)
9191
@test v[p] == si
@@ -99,7 +99,7 @@ for n in [0:10..., 100, 101, 1000, 1001]
9999

100100
v = randn_with_nans(n,0.1)
101101
for ord in [Base.Order.Forward, Base.Order.Reverse],
102-
alg in [TimSort, HeapSort, RadixSort]
102+
alg in [TimSort, HeapSort, RadixSort, CombSort]
103103
# test float sorting with NaNs
104104
s = sort(v, alg=alg, order=ord)
105105
@test issorted(s, order=ord)

0 commit comments

Comments
 (0)