@@ -19,12 +19,12 @@ struct CombSortAlg <: Algorithm end
1919struct PagedMergeSortAlg <: Algorithm end
2020struct ThreadedPagedMergeSortAlg <: Algorithm end
2121
22- function maybe_optimize (x:: Algorithm )
22+ function maybe_optimize (x:: Algorithm )
2323 isdefined (Base. Sort, :InitialOptimizations ) ? Base. Sort. InitialOptimizations (x) : x
24- end
24+ end
2525const HeapSort = maybe_optimize (HeapSortAlg ())
2626const TimSort = maybe_optimize (TimSortAlg ())
27- # Whenever InitialOptimizations is defined, RadixSort falls
27+ # Whenever InitialOptimizations is defined, RadixSort falls
2828# back to Base.DEFAULT_STABLE which already incldues them.
2929const RadixSort = RadixSortAlg ()
3030
@@ -688,24 +688,23 @@ end
688688# PagedMergeSort
689689# ##
690690
691- # merge v[lo:m] and v[m+1:hi] ([A;B]) using buffer t[1:1+hi-lo]
692- # this is faster than merge! but requires twice as much auxiliary memory.
691+ # merge v[lo:m] and v[m+1:hi] ([A;B]) using buffer t[1:1+hi-lo]
692+ # This is faster than merge! but requires twice as much auxiliary memory.
693693function twoended_merge! (v:: AbstractVector{T} , lo:: Integer , m:: Integer , hi:: Integer , o:: Ordering , t:: AbstractVector{T} ) where T
694- @assert lo <= m <= hi
695-
694+ @assert lo ≤ m ≤ hi
695+ @assert abs ((m- lo) - (hi- (m+ 1 ))) ≤ 1 " twoended_merge! only supports balanced merges"
696+ len = 1 + hi - lo
696697 # input array indices
697698 a_lo = lo
698699 a_hi = m
699- b_lo = m + 1
700+ b_lo = m + 1
700701 b_hi = hi
701702 # output array indices
702703 k_lo = 1
703- k_hi = 1 + hi - lo
704-
704+ k_hi = len
705705 @inbounds begin
706706 # two ended merge
707- # while at least 2 elements remain in both A and B
708- while a_lo < a_hi && b_lo < b_hi
707+ while k_lo <= len ÷ 2
709708 if lt (o, v[b_lo], v[a_lo])
710709 t[k_lo] = v[b_lo]
711710 b_lo += 1
@@ -723,32 +722,15 @@ function twoended_merge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Inte
723722 end
724723 k_hi -= 1
725724 end
726- # regular merge
727- # until either A or B runs out
728- while a_lo <= a_hi && b_lo <= b_hi
729- if lt (o, v[b_lo], v[a_lo])
730- t[k_lo] = v[b_lo]
731- b_lo += 1
732- else
733- t[k_lo] = v[a_lo]
734- a_lo += 1
735- end
736- k_lo += 1
737- end
738- # either A or B is empty -> copy remaining items
739- while a_lo <= a_hi
725+ # if the input length is odd,
726+ # one item remains
727+ if a_lo <= a_hi
740728 t[k_lo] = v[a_lo]
741- a_lo += 1
742- k_lo += 1
743- end
744- while b_lo <= b_hi
729+ elseif b_lo <= b_hi
745730 t[k_lo] = v[b_lo]
746- b_lo += 1
747- k_lo += 1
748731 end
749732 # copy back from t to v
750733 offset = lo- 1
751- len = 1 + hi - lo
752734 for i = 1 : len
753735 v[offset+ i] = t[i]
754736 end
0 commit comments