[algo] Add stable sort algorithm, using merge sort.
This commit is contained in:
parent
c58edfa486
commit
d3129070d9
70
algo.lua
70
algo.lua
|
@ -139,4 +139,74 @@ function algo.bsearchr(array, what, less)
|
|||
return lo + ofs
|
||||
end
|
||||
|
||||
local function merge(array, lo, mid, hi, less, workspace)
|
||||
local i, j, k
|
||||
i = 1
|
||||
|
||||
-- Copy first half of array to auxiliary array
|
||||
for j = lo,mid do
|
||||
workspace[i] = array[j]
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
i = 1
|
||||
j = mid + 1
|
||||
k = lo
|
||||
while k < j and j <= hi do
|
||||
local v = array[j]
|
||||
local el = workspace[i]
|
||||
|
||||
if less(v, el) then
|
||||
array[k] = v
|
||||
j = j + 1
|
||||
else
|
||||
array[k] = el
|
||||
i = i + 1
|
||||
end
|
||||
k = k + 1
|
||||
end
|
||||
|
||||
-- Copy back any remaining elements of first half
|
||||
for k = k,j-1 do
|
||||
array[k] = workspace[i]
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
local function mergesort(array, lo, hi, less, workspace)
|
||||
if hi - lo < 72 then
|
||||
_insertionsort(array, lo, hi, less)
|
||||
else
|
||||
local mid = floor((lo + hi)/2)
|
||||
|
||||
mergesort(array, lo, mid, less, workspace)
|
||||
mergesort(array, mid + 1, hi, less, workspace)
|
||||
merge(array, lo, mid, hi, less, workspace)
|
||||
end
|
||||
end
|
||||
|
||||
--- Array stable sort, uses Merge Sort - O(n*log(n)).
|
||||
--
|
||||
-- Algorithm is a slightly altered version of stable_sort(),
|
||||
-- posted on Lua-L by Steve Fisher on 02 May 2013 22:10:50
|
||||
-- https://lua-users.org/lists/lua-l/2013-05/msg00038.html
|
||||
--
|
||||
-- This implementation uses an auxiliary buffer of size O(n/2).
|
||||
--
|
||||
-- @tparam table array Array to be sorted.
|
||||
-- @tparam[opt=operator <] function less comparison function, takes 2 arguments,
|
||||
-- returns true if its first argument is
|
||||
-- less than its second argument,
|
||||
-- false otherwise.
|
||||
-- @tparam[opt={}] table use an existing workspace buffer instead of allocating one.
|
||||
function algo.stablesort(array, less, workspace)
|
||||
local n = #array
|
||||
|
||||
less = less or lt
|
||||
workspace = workspace or {}
|
||||
workspace[floor((n+1)/2)] = array[1] -- preallocate some room
|
||||
|
||||
mergesort(array, 1, n, less, workspace)
|
||||
end
|
||||
|
||||
return algo
|
||||
|
|
Loading…
Reference in New Issue