1
0
Fork 0
AllTheLittleThings/PriorityQueue.lua
2011-05-30 13:01:19 -04:00

109 lines
No EOL
2.2 KiB
Lua

PriorityQueue = {
size = 0,
heap = {},
cmp = function(a,b) return a<b end;
};
local PriorityQueue = PriorityQueue;
local function deepcopy(dst, src)
for k,v in pairs(src) do
if (type(v) == "table") then
dst[k] = {};
deepcopy(dst[k], v);
else
dst[k] = v;
end
end
end
-- ---------------------------
-- ----------- API -----------
-- ---------------------------
-- local pq = PriorityQueue:New();
-- local pq = PriorityQueue:New{ default=1, values=2 };
function PriorityQueue:New(init)
local pq = {};
deepcopy(pq, self);
if (init) then
for k,v in pairs(init) do
table.insert(pq.heap, {key=k, val=v});
pq.size = pq.size + 1;
end
for i=#pq.heap,1,-1 do
pq:PushDown(i);
end
end
return pq;
end
-- pq:Insert(key, priority);
function PriorityQueue:Insert(key, value)
if (not key or not value) then
error("Usage - myPriorityQueue:Insert(key, value);");
end
local i = self.size+1;
local parent = floor(i/2);
if (type(self.heap[i]) == "table") then
self.heap[i].key = key;
self.heap[i].val = value;
else
self.heap[i] = {key=key, val=value};
end
self.size = self.size + 1;
while (parent>0 and self:Compare(i, parent)) do
self:Swap(i, parent);
i = parent;
parent = floor(i/2);
end
end
-- local next = pq:Peek();
function PriorityQueue:Peek()
if (self.size <= 0) then
return nil;
end
local node = self.heap[1];
return node.key, node.val;
end
-- local next = pq:Remove();
function PriorityQueue:Remove()
if (self.size <= 0) then
return nil;
end
self:Swap(1, self.size);
self:PushDown(1);
self.size = self.size - 1;
local node = self.heap[self.size+1];
return node.key, node.val;
end
-- ---------------------------
-- ------ Class Methods ------
-- ---------------------------
function PriorityQueue:PushDown(index)
local lc = index*2;
local rc = lc + 1;
if (lc <= self.size) then
if (rc <= self.size and self:Compare(rc, lc)) then
rc = lc;
end
if (self:Compare(lc, index)) then
self:Swap(lc, index);
end
end
end
function PriorityQueue:Swap(i, j)
local temp = self.heap[i];
self.heap[i] = self.heap[j];
self.heap[j] = temp;
end
function PriorityQueue:Compare(i, j)
return self.cmp(self.heap[i].val, self.heap[j].val);
end