mirror of
https://github.com/1bardesign/batteries.git
synced 2024-11-22 22:24:35 +00:00
[modified] clean up source of stable_sort.lua
This commit is contained in:
parent
94005675e9
commit
27b73543e0
@ -43,13 +43,13 @@ local _sort_core = {}
|
|||||||
--tunable size for
|
--tunable size for
|
||||||
_sort_core.max_chunk_size = 24
|
_sort_core.max_chunk_size = 24
|
||||||
|
|
||||||
function _sort_core.insertion_sort_impl( array, first, last, less )
|
function _sort_core.insertion_sort_impl(array, first, last, less)
|
||||||
for i = first + 1, last do
|
for i = first + 1, last do
|
||||||
local k = first
|
local k = first
|
||||||
local v = array[i]
|
local v = array[i]
|
||||||
for j = i, first + 1, -1 do
|
for j = i, first + 1, -1 do
|
||||||
if less( v, array[j-1] ) then
|
if less(v, array[j - 1]) then
|
||||||
array[j] = array[j-1]
|
array[j] = array[j - 1]
|
||||||
else
|
else
|
||||||
k = j
|
k = j
|
||||||
break
|
break
|
||||||
@ -59,12 +59,12 @@ function _sort_core.insertion_sort_impl( array, first, last, less )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function _sort_core.merge( array, workspace, low, middle, high, less )
|
function _sort_core.merge(array, workspace, low, middle, high, less)
|
||||||
local i, j, k
|
local i, j, k
|
||||||
i = 1
|
i = 1
|
||||||
-- copy first half of array to auxiliary array
|
-- copy first half of array to auxiliary array
|
||||||
for j = low, middle do
|
for j = low, middle do
|
||||||
workspace[ i ] = array[ j ]
|
workspace[i] = array[j]
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
-- sieve through
|
-- sieve through
|
||||||
@ -75,18 +75,18 @@ function _sort_core.merge( array, workspace, low, middle, high, less )
|
|||||||
if (k >= j) or (j > high) then
|
if (k >= j) or (j > high) then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
if less( array[ j ], workspace[ i ] ) then
|
if less(array[j], workspace[i]) then
|
||||||
array[ k ] = array[ j ]
|
array[k] = array[j]
|
||||||
j = j + 1
|
j = j + 1
|
||||||
else
|
else
|
||||||
array[ k ] = workspace[ i ]
|
array[k] = workspace[i]
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
k = k + 1
|
k = k + 1
|
||||||
end
|
end
|
||||||
-- copy back any remaining elements of first half
|
-- copy back any remaining elements of first half
|
||||||
for k = k, j-1 do
|
for k = k, j - 1 do
|
||||||
array[ k ] = workspace[ i ]
|
array[k] = workspace[i]
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -94,30 +94,31 @@ end
|
|||||||
|
|
||||||
function _sort_core.merge_sort_impl(array, workspace, low, high, less)
|
function _sort_core.merge_sort_impl(array, workspace, low, high, less)
|
||||||
if high - low <= _sort_core.max_chunk_size then
|
if high - low <= _sort_core.max_chunk_size then
|
||||||
_sort_core.insertion_sort_impl( array, low, high, less )
|
_sort_core.insertion_sort_impl(array, low, high, less)
|
||||||
else
|
else
|
||||||
local middle = math.floor((low + high)/2)
|
local middle = math.floor((low + high) / 2)
|
||||||
_sort_core.merge_sort_impl( array, workspace, low, middle, less )
|
_sort_core.merge_sort_impl(array, workspace, low, middle, less)
|
||||||
_sort_core.merge_sort_impl( array, workspace, middle + 1, high, less )
|
_sort_core.merge_sort_impl(array, workspace, middle + 1, high, less)
|
||||||
_sort_core.merge( array, workspace, low, middle, high, less )
|
_sort_core.merge(array, workspace, low, middle, high, less)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function default_less(a, b)
|
||||||
|
return a < b
|
||||||
|
end
|
||||||
|
|
||||||
--inline common setup stuff
|
--inline common setup stuff
|
||||||
function _sort_core.sort_setup(array, less)
|
function _sort_core.sort_setup(array, less)
|
||||||
|
--default less
|
||||||
|
less = less or default_less
|
||||||
|
--
|
||||||
local n = #array
|
local n = #array
|
||||||
local trivial = false
|
|
||||||
--trivial cases; empty or 1 element
|
--trivial cases; empty or 1 element
|
||||||
if n <= 1 then
|
local trivial = (n <= 1)
|
||||||
trivial = true
|
if not trivial then
|
||||||
else
|
|
||||||
--default less
|
|
||||||
less = less or function (a, b)
|
|
||||||
return a < b
|
|
||||||
end
|
|
||||||
--check less
|
--check less
|
||||||
if less(array[1], array[1]) then
|
if less(array[1], array[1]) then
|
||||||
error("invalid order function for sorting")
|
error("invalid order function for sorting; less(v, v) should not be true for any v.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--setup complete
|
--setup complete
|
||||||
@ -128,9 +129,10 @@ function _sort_core.stable_sort(array, less)
|
|||||||
--setup
|
--setup
|
||||||
local trivial, n, less = _sort_core.sort_setup(array, less)
|
local trivial, n, less = _sort_core.sort_setup(array, less)
|
||||||
if not trivial then
|
if not trivial then
|
||||||
--temp storage
|
--temp storage; allocate ahead of time
|
||||||
local workspace = {}
|
local workspace = {}
|
||||||
workspace[ math.floor( (n+1)/2 ) ] = array[1]
|
local middle = math.ceil(n / 2)
|
||||||
|
workspace[middle] = array[1]
|
||||||
--dive in
|
--dive in
|
||||||
_sort_core.merge_sort_impl( array, workspace, 1, n, less )
|
_sort_core.merge_sort_impl( array, workspace, 1, n, less )
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user