Add files
This commit is contained in:
108
pQueue
Normal file
108
pQueue
Normal file
@@ -0,0 +1,108 @@
|
||||
local function sift_up(queue, index)
|
||||
local current, parent = index, (index - (index % 2))/2
|
||||
while current > 1 and queue.cmp(queue[current][2], queue[parent][2]) do
|
||||
queue[current], queue[parent] = queue[parent], queue[current]
|
||||
current, parent = parent, (parent - (parent % 2))/2
|
||||
end
|
||||
return current
|
||||
end
|
||||
|
||||
local function sift_down(queue, index)
|
||||
local current, child, size = index, 2*index, #queue
|
||||
while child <= size do
|
||||
if child < size and queue.cmp(queue[child + 1][2], queue[child][2]) then
|
||||
child = child + 1
|
||||
end
|
||||
if queue.cmp(queue[child][2], queue[current][2]) then
|
||||
queue[current], queue[child] = queue[child], queue[current]
|
||||
current, child = child, 2*child
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
return current
|
||||
end
|
||||
|
||||
local methods = {
|
||||
|
||||
insert = function(self, element, value)
|
||||
table.insert(self, {element, value})
|
||||
return sift_up(self, #self)
|
||||
end,
|
||||
|
||||
remove = function(self, element, compFunc)
|
||||
local index = self:contains(element, compFunc)
|
||||
if index then
|
||||
local size = #self
|
||||
self[index], self[size] = self[size], self[index]
|
||||
local ret = table.remove(self)
|
||||
if size > 1 and index < size then
|
||||
sift_down(self, index)
|
||||
if index > 1 then
|
||||
sift_up(self, index)
|
||||
end
|
||||
end
|
||||
return unpack(ret)
|
||||
end
|
||||
end,
|
||||
|
||||
pop = function(self)
|
||||
if self[1] then
|
||||
local size = #self
|
||||
self[1], self[size] = self[size], self[1]
|
||||
local ret = table.remove(self)
|
||||
if size > 1 then
|
||||
sift_down(self, 1)
|
||||
end
|
||||
return unpack(ret)
|
||||
end
|
||||
end,
|
||||
|
||||
peek = function(self)
|
||||
if self[1] then
|
||||
return self[1][1], self[1][2]
|
||||
end
|
||||
end,
|
||||
|
||||
contains = function(self, element, compFunc)
|
||||
for index, entry in ipairs(self) do
|
||||
if (compFunc and compFunc(entry[1], element)) or entry[1] == element then
|
||||
return index
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
isEmpty = function(self)
|
||||
return #self == 0
|
||||
end,
|
||||
|
||||
size = function(self)
|
||||
return #self
|
||||
end,
|
||||
|
||||
getValue = function(self, element, compFunc)
|
||||
local index = self:contains(element, compFunc)
|
||||
return (index and self[index][2]) or false
|
||||
end,
|
||||
|
||||
setValue = function(self, element, value, compFunc)
|
||||
local index = self:contains(element, compFunc)
|
||||
if index then
|
||||
self[index][2] = value
|
||||
sift_up(self, index)
|
||||
sift_down(self, index)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
function new(compareFunc)
|
||||
local queue = {}
|
||||
queue.cmp = type(compareFunc) == "function" and compareFunc or function(a, b) return a < b end
|
||||
setmetatable(queue, {__index = methods})
|
||||
return queue
|
||||
end
|
||||
Reference in New Issue
Block a user