added binary search to insert_sorted

Added method tablex.is_sorted
This commit is contained in:
Alvaro Frias Garay 2021-04-15 21:09:04 -03:00
parent dbadd9af83
commit 5ed6d68f6c

View File

@ -48,12 +48,27 @@ function tablex.unshift(t, v)
return t return t
end end
function tablex.is_sorted(t)
local sorted = true
for i = 1, #t - 1 do
if t[i] > t[i + 1] then
sorted = false
break
end
end
return sorted
end
--insert to the first position before the first larger element in the table --insert to the first position before the first larger element in the table
--if this is used on an already sorted table, the table will remain sorted and not need re-sorting --if this is used on an already sorted table, the table will remain sorted and not need re-sorting
--todo: make it do binary search rather than linear to improve performance --todo: make it do binary search rather than linear to improve performance
--return the table for possible chaining --return the table for possible chaining
function tablex.insert_sorted(t, v, less) function tablex.insert_sorted(t, v, less)
local inserted = false local inserted = false
-- to use binary search is necessary as precondition that
-- the table is sorted
if not tablex.is_sorted(t) then
for i = 1, #t do for i = 1, #t do
if less(v, t[i]) then if less(v, t[i]) then
table.insert(t, i, v) table.insert(t, i, v)
@ -67,6 +82,34 @@ function tablex.insert_sorted(t, v, less)
return t return t
end end
local l = 1
local r = #t
if r < l then
table.insert(t,v)
return t
end
while l <= r do
local mid = math.floor(l + (r - l) / 2)
if (less(v, t[mid]) or v == t[mid]) and (mid == 1 or less(t[mid - 1], v) or t[mid - 1] == v) then
table.insert(t, mid, v)
inserted = true
break
elseif less(t[mid], v) then
l = mid + 1
elseif less(v, t[mid - 1]) then
r = mid - 1
end
end
if not inserted then
table.insert(t, l, v)
end
return t
end
--find the index in a sequential table that a resides at --find the index in a sequential table that a resides at
--or nil if nothing was found --or nil if nothing was found
function tablex.index_of(t, a) function tablex.index_of(t, a)