835 lines
20 KiB
Lua
835 lines
20 KiB
Lua
|
|
local bh = require('binaryheap')
|
|
|
|
local data = {
|
|
{ value = 98, payload = "pos08" }, -- 1
|
|
{ value = 28, payload = "pos05" }, -- 2
|
|
{ value = 36, payload = "pos06" }, -- 3
|
|
{ value = 48, payload = "pos09" }, -- 4
|
|
{ value = 68, payload = "pos10" }, -- 5
|
|
{ value = 58, payload = "pos13" }, -- 6
|
|
{ value = 80, payload = "pos15" }, -- 7
|
|
{ value = 46, payload = "pos04" }, -- 8
|
|
{ value = 19, payload = "pos03" }, -- 9
|
|
{ value = 66, payload = "pos11" }, -- 10
|
|
{ value = 22, payload = "pos02" }, -- 11
|
|
{ value = 60, payload = "pos12" }, -- 12
|
|
{ value = 15, payload = "pos01" }, -- 13
|
|
{ value = 83, payload = "pos14" }, -- 14
|
|
{ value = 59, payload = "pos07" }, -- 15
|
|
}
|
|
|
|
local sort = function(t)
|
|
table.sort(t, function(a,b) return (a.value < b.value) end)
|
|
return t
|
|
end
|
|
|
|
local function check(heap)
|
|
for pos = 2, #heap.values do
|
|
local parent = math.floor(pos / 2)
|
|
assert(not heap.lt(heap.values[pos], heap.values[parent]))
|
|
end
|
|
if heap.payloads then
|
|
for pos in ipairs(heap.values) do
|
|
local payload = heap.payloads[pos]
|
|
assert(heap.reverse[payload] == pos)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function newheap()
|
|
-- create a heap with data
|
|
local heap = bh.minUnique()
|
|
for _, node in ipairs(data) do
|
|
heap:insert(node.value,node.payload)
|
|
check(heap)
|
|
end
|
|
|
|
-- create a sorted list with data, sorted by 'value'
|
|
local sorted = {}
|
|
for k,v in pairs(data) do sorted[k] = v end
|
|
sort(sorted)
|
|
-- create a reverse list of the sorted table; returns sorted-index, based on 'value'
|
|
local sreverse = {}
|
|
for i,v in ipairs(sorted) do
|
|
sreverse[v.value] = i
|
|
end
|
|
return heap, sorted, sreverse
|
|
end
|
|
|
|
local function testheap(heap, sorted)
|
|
while sorted[1] do
|
|
local value1, payload1
|
|
if heap.reverse then
|
|
-- it is a unique heap
|
|
payload1, value1 = heap:pop()
|
|
else
|
|
-- it is a plain heap
|
|
value1, payload1 = heap:pop()
|
|
end
|
|
local value2, payload2 = sorted[1].value, sorted[1].payload
|
|
table.remove(sorted, 1)
|
|
assert.are.equal(payload1, payload2)
|
|
assert.are.equal(value1, value2)
|
|
end
|
|
end
|
|
|
|
describe("[minUnique]", function()
|
|
|
|
it("validates order of insertion", function()
|
|
local h = newheap()
|
|
assert.are.equal(h.payloads[1], data[13].payload)
|
|
assert.are.equal(h.payloads[2], data[11].payload)
|
|
assert.are.equal(h.payloads[3], data[9].payload)
|
|
assert.are.equal(h.payloads[4], data[8].payload)
|
|
assert.are.equal(h.payloads[5], data[2].payload)
|
|
assert.are.equal(h.payloads[6], data[3].payload)
|
|
assert.are.equal(h.payloads[7], data[15].payload)
|
|
assert.are.equal(h.payloads[8], data[1].payload)
|
|
assert.are.equal(h.payloads[9], data[4].payload)
|
|
assert.are.equal(h.payloads[10], data[5].payload)
|
|
assert.are.equal(h.payloads[11], data[10].payload)
|
|
assert.are.equal(h.payloads[12], data[12].payload)
|
|
assert.are.equal(h.payloads[13], data[6].payload)
|
|
assert.are.equal(h.payloads[14], data[14].payload)
|
|
assert.are.equal(h.payloads[15], data[7].payload)
|
|
end)
|
|
|
|
it("validates order of popping", function()
|
|
testheap(newheap())
|
|
end)
|
|
|
|
it("peek()", function()
|
|
local heap, sorted = newheap()
|
|
local payload, value = heap:peek()
|
|
-- correct values?
|
|
assert.are.equal(value, sorted[1].value)
|
|
assert.are.equal(payload, sorted[1].payload)
|
|
-- are they still on the heap?
|
|
assert.are.equal(value, heap.values[1])
|
|
assert.are.equal(payload, heap.payloads[1])
|
|
end)
|
|
|
|
it("peekValue()", function()
|
|
local h = bh.minUnique()
|
|
h:insert(1, 11)
|
|
assert.equal(1, h:peekValue(11))
|
|
-- try again empty
|
|
h:pop()
|
|
assert.is_nil(h:peekValue(11))
|
|
end)
|
|
|
|
it("pop()", function()
|
|
local h = bh.minUnique()
|
|
h:insert(3, 13)
|
|
h:insert(2, 12)
|
|
h:insert(1, 11)
|
|
-- try again empty
|
|
local pl, v
|
|
pl, v = h:pop()
|
|
assert.equal(v, 1)
|
|
assert.equal(pl, 11)
|
|
pl, v = h:pop()
|
|
assert.equal(v, 2)
|
|
assert.equal(pl, 12)
|
|
pl, v = h:pop()
|
|
assert.equal(v, 3)
|
|
assert.equal(pl, 13)
|
|
pl, v = h:pop()
|
|
assert.is_nil(v)
|
|
assert.is_nil(pl)
|
|
end)
|
|
|
|
describe("remove()", function()
|
|
it("a middle item", function()
|
|
local heap, sorted = newheap()
|
|
local idx = 4
|
|
local value = sorted[idx].value
|
|
local payload = sorted[idx].payload
|
|
local v, pl = heap:remove(payload)
|
|
check(heap)
|
|
-- did we get the right ones?
|
|
assert.are.equal(value, v)
|
|
assert.are.equal(payload, pl)
|
|
assert.is.Nil(heap[payload])
|
|
-- remove from test data and compare
|
|
table.remove(sorted, idx)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("the last item (of the array)", function()
|
|
local heap, sorted = newheap()
|
|
local idx = #heap.values
|
|
local value = sorted[idx].value
|
|
local payload = sorted[idx].payload
|
|
local v, pl = heap:remove(payload)
|
|
check(heap)
|
|
-- did we get the right ones?
|
|
assert.are.equal(value, v)
|
|
assert.are.equal(payload, pl)
|
|
assert.is.Nil(heap.reverse[payload])
|
|
-- remove from test data and compare
|
|
table.remove(sorted, idx)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("non existing payload returns nil", function()
|
|
local heap = newheap()
|
|
local v, pl = heap:remove({})
|
|
assert.is_nil(v)
|
|
assert.is_nil(pl)
|
|
end)
|
|
|
|
it("nil payload returns nil", function()
|
|
local heap = newheap()
|
|
local v, pl = heap:remove(nil)
|
|
assert.is_nil(v)
|
|
assert.is_nil(pl)
|
|
end)
|
|
|
|
it("with repeated values", function()
|
|
local h = bh.minUnique()
|
|
h:insert(1, 11)
|
|
check(h)
|
|
h:insert(1, 12)
|
|
check(h)
|
|
local value, payload
|
|
value, payload = h:remove(11)
|
|
check(h)
|
|
assert.equal(1, value)
|
|
assert.equal(11, payload)
|
|
payload, value = h:peek()
|
|
assert.equal(1, value)
|
|
assert.equal(12, payload)
|
|
assert.same({1}, h.values)
|
|
assert.same({12}, h.payloads)
|
|
assert.same({[12]=1}, h.reverse)
|
|
end)
|
|
end)
|
|
|
|
describe("insert()", function()
|
|
it("a top item", function()
|
|
local heap, sorted = newheap()
|
|
local nvalue = sorted[1].value - 10
|
|
local npayload = {}
|
|
table.insert(sorted, 1, {})
|
|
sorted[1].value = nvalue
|
|
sorted[1].payload = npayload
|
|
heap:insert(nvalue, npayload)
|
|
check(heap)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("a middle item", function()
|
|
local heap, sorted = newheap()
|
|
local nvalue = 57
|
|
local npayload = {}
|
|
table.insert(sorted, { value = nvalue, payload = npayload })
|
|
sort(sorted)
|
|
heap:insert(nvalue, npayload)
|
|
check(heap)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("a last item", function()
|
|
local heap, sorted = newheap()
|
|
local nvalue = sorted[#sorted].value + 10
|
|
local npayload = {}
|
|
table.insert(sorted, {})
|
|
sorted[#sorted].value = nvalue
|
|
sorted[#sorted].payload = npayload
|
|
heap:insert(nvalue, npayload)
|
|
check(heap)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("a nil value throws an error", function()
|
|
local heap = newheap()
|
|
assert.has.error(function()
|
|
heap:insert(nil, "something")
|
|
end)
|
|
end)
|
|
|
|
it("a nil payload throws an error", function()
|
|
local heap = newheap()
|
|
assert.has.error(function()
|
|
heap:insert(15, nil)
|
|
end)
|
|
end)
|
|
|
|
it("a duplicate payload throws an error", function()
|
|
local heap = newheap()
|
|
local value = {}
|
|
heap:insert(1, value)
|
|
assert.has.error(function()
|
|
heap:insert(2, value)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("update()", function()
|
|
it("a top item", function()
|
|
local heap, sorted = newheap()
|
|
local idx = 1
|
|
local payload = sorted[idx].payload
|
|
local nvalue = sorted[#sorted].value + 1 -- move to end with new value
|
|
sorted[idx].value = nvalue
|
|
sort(sorted)
|
|
heap:update(payload, nvalue)
|
|
check(heap)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("a middle item", function()
|
|
local heap, sorted = newheap()
|
|
local idx = 4
|
|
local payload = sorted[idx].payload
|
|
local nvalue = sorted[idx].value * 2
|
|
sorted[idx].value = nvalue
|
|
sort(sorted)
|
|
heap:update(payload, nvalue)
|
|
check(heap)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("a last item", function()
|
|
local heap, sorted = newheap()
|
|
local idx = #sorted
|
|
local payload = sorted[idx].payload
|
|
local nvalue = sorted[1].value - 1 -- move to top with new value
|
|
sorted[idx].value = nvalue
|
|
sort(sorted)
|
|
heap:update(payload, nvalue)
|
|
check(heap)
|
|
testheap(heap, sorted)
|
|
end)
|
|
|
|
it("a nil value throws an error", function()
|
|
local heap, sorted = newheap()
|
|
local idx = #sorted
|
|
local payload = sorted[idx].payload
|
|
assert.has.error(function()
|
|
heap:update(payload, nil)
|
|
end)
|
|
end)
|
|
|
|
it("an unknown payload throws an error", function()
|
|
local heap = newheap()
|
|
assert.has.error(function()
|
|
heap:update({}, 10)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("size()", function()
|
|
it("returns number of elements", function()
|
|
local h = bh.minUnique()
|
|
assert.equal(0, h:size())
|
|
h:insert(1, -1)
|
|
assert.equal(1, h:size())
|
|
h:insert(2, -2)
|
|
assert.equal(2, h:size())
|
|
h:insert(3, -3)
|
|
assert.equal(3, h:size())
|
|
h:insert(4, -4)
|
|
assert.equal(4, h:size())
|
|
h:insert(5, -5)
|
|
assert.equal(5, h:size())
|
|
h:pop()
|
|
assert.equal(4, h:size())
|
|
h:pop()
|
|
assert.equal(3, h:size())
|
|
h:pop()
|
|
assert.equal(2, h:size())
|
|
h:pop()
|
|
assert.equal(1, h:size())
|
|
h:pop()
|
|
assert.equal(0, h:size())
|
|
end)
|
|
end)
|
|
|
|
describe("valueByPayload()", function()
|
|
it("gets value by payload", function()
|
|
local h = bh.minUnique()
|
|
h:insert(1, -1)
|
|
h:insert(2, -2)
|
|
h:insert(3, -3)
|
|
h:insert(4, -4)
|
|
h:insert(5, -5)
|
|
assert.equal(1, h:valueByPayload((-1)))
|
|
assert.equal(2, h:valueByPayload((-2)))
|
|
assert.equal(3, h:valueByPayload((-3)))
|
|
assert.equal(4, h:valueByPayload((-4)))
|
|
assert.equal(5, h:valueByPayload((-5)))
|
|
h:remove(-1)
|
|
assert.falsy(h:valueByPayload((-1)))
|
|
end)
|
|
|
|
it("non existing payload returns nil", function()
|
|
local h = bh.minUnique()
|
|
h:insert(1, -1)
|
|
h:insert(2, -2)
|
|
h:insert(3, -3)
|
|
h:insert(4, -4)
|
|
h:insert(5, -5)
|
|
assert.is_nil(h:valueByPayload({}))
|
|
end)
|
|
|
|
it("nil payload returns nil", function()
|
|
local h = bh.minUnique()
|
|
h:insert(1, -1)
|
|
h:insert(2, -2)
|
|
h:insert(3, -3)
|
|
h:insert(4, -4)
|
|
h:insert(5, -5)
|
|
assert.is_nil(h:valueByPayload(nil))
|
|
end)
|
|
end)
|
|
|
|
it("creates minUnique with custom less-than function", function()
|
|
local h = bh.minUnique(function (a, b)
|
|
return math.abs(a) < math.abs(b)
|
|
end)
|
|
h:insert(1, -1)
|
|
check(h)
|
|
h:insert(-2, 2)
|
|
check(h)
|
|
h:insert(3, -3)
|
|
check(h)
|
|
h:insert(-4, 4)
|
|
check(h)
|
|
h:insert(5, -5)
|
|
check(h)
|
|
local value, payload
|
|
payload, value = h:peek()
|
|
assert.equal(1, value)
|
|
assert.equal(-1, payload)
|
|
h:pop()
|
|
check(h)
|
|
payload, value = h:peek()
|
|
assert.equal(-2, value)
|
|
assert.equal(2, payload)
|
|
end)
|
|
end)
|
|
|
|
describe("[maxUnique]", function()
|
|
it("creates maxUnique with custom less-than function", function()
|
|
local h = bh.maxUnique(function (a, b)
|
|
return math.abs(a) > math.abs(b)
|
|
end)
|
|
h:insert(1, -1)
|
|
check(h)
|
|
h:insert(-2, 2)
|
|
check(h)
|
|
h:insert(3, -3)
|
|
check(h)
|
|
h:insert(-4, 4)
|
|
check(h)
|
|
h:insert(5, -5)
|
|
check(h)
|
|
local value, payload
|
|
payload, value = h:peek()
|
|
assert.equal(5, value)
|
|
assert.equal(-5, payload)
|
|
h:pop()
|
|
check(h)
|
|
payload, value = h:peek()
|
|
assert.equal(-4, value)
|
|
assert.equal(4, payload)
|
|
end)
|
|
end)
|
|
|
|
describe("[minHeap]", function()
|
|
it("creates minHeap", function()
|
|
local h = bh.minHeap()
|
|
check(h)
|
|
end)
|
|
|
|
describe("insert()", function()
|
|
it("a number into minHeap", function()
|
|
local h = bh.minHeap()
|
|
h:insert(42)
|
|
check(h)
|
|
end)
|
|
|
|
it("nil throws an error", function()
|
|
local h = bh.minHeap()
|
|
assert.has.error(function()
|
|
h:insert(nil)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("remove()", function()
|
|
it("a position", function()
|
|
local h = bh.minHeap()
|
|
h:insert(42)
|
|
h:insert(43)
|
|
assert.equal(43, h:remove(2))
|
|
check(h)
|
|
end)
|
|
|
|
it("a bad position returns nil", function()
|
|
local h = bh.minHeap()
|
|
h:insert(42)
|
|
h:insert(43)
|
|
assert.is_nil(h:remove(0))
|
|
assert.is_nil(h:remove(3))
|
|
check(h)
|
|
end)
|
|
end)
|
|
|
|
describe("size()", function()
|
|
it("returns number of elements", function()
|
|
local h = bh.minHeap()
|
|
assert.equal(0, h:size())
|
|
h:insert(1)
|
|
assert.equal(1, h:size())
|
|
h:insert(2)
|
|
assert.equal(2, h:size())
|
|
h:insert(3)
|
|
assert.equal(3, h:size())
|
|
h:insert(4)
|
|
assert.equal(4, h:size())
|
|
h:insert(5)
|
|
assert.equal(5, h:size())
|
|
h:pop()
|
|
assert.equal(4, h:size())
|
|
h:pop()
|
|
assert.equal(3, h:size())
|
|
h:pop()
|
|
assert.equal(2, h:size())
|
|
h:pop()
|
|
assert.equal(1, h:size())
|
|
h:pop()
|
|
assert.equal(0, h:size())
|
|
end)
|
|
end)
|
|
|
|
describe("peek()", function()
|
|
it("return nil in empty minHeap", function()
|
|
local h = bh.minHeap()
|
|
assert.is_nil(h:peek())
|
|
check(h)
|
|
end)
|
|
|
|
it("minHeap of one element", function()
|
|
local h = bh.minHeap()
|
|
h:insert(42)
|
|
check(h)
|
|
local value, payload = h:peek()
|
|
assert.equal(42, value)
|
|
assert.falsy(payload)
|
|
end)
|
|
|
|
it("minHeap of two elements", function()
|
|
local h = bh.minHeap()
|
|
h:insert(42)
|
|
check(h)
|
|
h:insert(1)
|
|
check(h)
|
|
local value, payload = h:peek()
|
|
assert.equal(1, value)
|
|
assert.falsy(payload)
|
|
end)
|
|
|
|
it("minHeap of 10 elements", function()
|
|
local h = bh.minHeap()
|
|
h:insert(10)
|
|
h:insert(7)
|
|
h:insert(1)
|
|
h:insert(5)
|
|
h:insert(6)
|
|
h:insert(9)
|
|
h:insert(8)
|
|
h:insert(4)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
check(h)
|
|
local value, payload = h:peek()
|
|
assert.equal(1, value)
|
|
assert.falsy(payload)
|
|
end)
|
|
|
|
it("removes peek in minHeap of 5 elements", function()
|
|
local h = bh.minHeap()
|
|
h:insert(1)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
h:insert(4)
|
|
h:insert(5)
|
|
local value
|
|
value = h:pop()
|
|
check(h)
|
|
assert.equal(1, value)
|
|
value = h:peek()
|
|
assert.equal(2, value)
|
|
end)
|
|
end)
|
|
|
|
describe("update()", function()
|
|
it("in minHeap of 5 elements (pos 2 -> pos 1)", function()
|
|
local h = bh.minHeap()
|
|
h:insert(1)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
h:insert(4)
|
|
h:insert(5)
|
|
check(h)
|
|
h:update(2, -100)
|
|
check(h)
|
|
local value = h:peek()
|
|
assert.equal(-100, value)
|
|
end)
|
|
|
|
it("in minHeap of 5 elements (pos 1 -> pos 2)", function()
|
|
local h = bh.minHeap()
|
|
h:insert(1)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
h:insert(4)
|
|
h:insert(5)
|
|
check(h)
|
|
h:update(1, 100)
|
|
check(h)
|
|
local value = h:peek()
|
|
assert.equal(2, value)
|
|
end)
|
|
|
|
it("nil throws an error", function()
|
|
local h = bh.minHeap()
|
|
h:insert(10)
|
|
assert.has.error(function()
|
|
h:update(nil)
|
|
end)
|
|
end)
|
|
|
|
it("bad position throws an error", function()
|
|
local h = bh.minHeap()
|
|
h:insert(10)
|
|
assert.has.error(function()
|
|
h:update(0)
|
|
end)
|
|
assert.has.error(function()
|
|
h:update(2)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
it("creates minHeap with custom less-than function", function()
|
|
local h = bh.minHeap(function (a, b)
|
|
return math.abs(a) < math.abs(b)
|
|
end)
|
|
h:insert(1)
|
|
check(h)
|
|
h:insert(-2)
|
|
check(h)
|
|
h:insert(3)
|
|
check(h)
|
|
h:insert(-4)
|
|
check(h)
|
|
h:insert(5)
|
|
check(h)
|
|
assert.equal(1, h:peek())
|
|
h:pop()
|
|
check(h)
|
|
assert.equal(-2, h:peek())
|
|
end)
|
|
end)
|
|
|
|
|
|
describe("[maxHeap]", function()
|
|
it("creates maxHeap", function()
|
|
local h = bh.maxHeap()
|
|
check(h)
|
|
end)
|
|
|
|
describe("insert()", function()
|
|
it("inserts a number into maxHeap", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(42)
|
|
check(h)
|
|
end)
|
|
|
|
it("nil throws an error", function()
|
|
local h = bh.maxHeap()
|
|
assert.has.error(function()
|
|
h:insert(nil)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("remove()", function()
|
|
it("a position", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(42)
|
|
h:insert(43)
|
|
assert.equal(42, h:remove(2))
|
|
check(h)
|
|
end)
|
|
|
|
it("a bad position returns nil", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(42)
|
|
h:insert(43)
|
|
assert.is_nil(h:remove(0))
|
|
assert.is_nil(h:remove(3))
|
|
check(h)
|
|
end)
|
|
end)
|
|
|
|
describe("size()", function()
|
|
it("returns number of elements", function()
|
|
local h = bh.minHeap()
|
|
assert.equal(0, h:size())
|
|
h:insert(1)
|
|
assert.equal(1, h:size())
|
|
h:insert(2)
|
|
assert.equal(2, h:size())
|
|
h:insert(3)
|
|
assert.equal(3, h:size())
|
|
h:insert(4)
|
|
assert.equal(4, h:size())
|
|
h:insert(5)
|
|
assert.equal(5, h:size())
|
|
h:pop()
|
|
assert.equal(4, h:size())
|
|
h:pop()
|
|
assert.equal(3, h:size())
|
|
h:pop()
|
|
assert.equal(2, h:size())
|
|
h:pop()
|
|
assert.equal(1, h:size())
|
|
h:pop()
|
|
assert.equal(0, h:size())
|
|
end)
|
|
end)
|
|
|
|
describe("peek()", function()
|
|
it("return nil in empty maxHeap", function()
|
|
local h = bh.maxHeap()
|
|
assert.is_nil(h:peek())
|
|
check(h)
|
|
end)
|
|
|
|
it("maxHeap of one element", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(42)
|
|
check(h)
|
|
local value = h:peek()
|
|
assert.equal(42, value)
|
|
end)
|
|
|
|
it("maxHeap of two elements", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(42)
|
|
check(h)
|
|
h:insert(1)
|
|
check(h)
|
|
local value = h:peek()
|
|
assert.equal(42, value)
|
|
end)
|
|
|
|
it("maxHeap of 10 elements", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(10)
|
|
h:insert(7)
|
|
h:insert(1)
|
|
h:insert(5)
|
|
h:insert(6)
|
|
h:insert(9)
|
|
h:insert(8)
|
|
h:insert(4)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
check(h)
|
|
local value = h:peek()
|
|
assert.equal(10, value)
|
|
end)
|
|
|
|
it("removes peek in maxHeap of 5 elements", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(1)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
h:insert(4)
|
|
h:insert(5)
|
|
check(h)
|
|
local value
|
|
value = h:pop()
|
|
check(h)
|
|
assert.equal(5, value)
|
|
value = h:peek()
|
|
assert.equal(4, value)
|
|
end)
|
|
end)
|
|
|
|
describe("update()", function()
|
|
it("in maxHeap of 5 elements (pos 2 -> pos 1)", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(1)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
h:insert(4)
|
|
h:insert(5)
|
|
check(h)
|
|
h:update(2, 100)
|
|
check(h)
|
|
local value = h:peek()
|
|
assert.equal(100, value)
|
|
end)
|
|
|
|
it("in maxHeap of 5 elements (pos 1 -> pos 2)", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(1)
|
|
h:insert(2)
|
|
h:insert(3)
|
|
h:insert(4)
|
|
h:insert(5)
|
|
check(h)
|
|
h:update(1, -100)
|
|
check(h)
|
|
local value = h:peek()
|
|
assert.equal(4, value)
|
|
end)
|
|
|
|
it("nil throws an error", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(10)
|
|
assert.has.error(function()
|
|
h:update(nil)
|
|
end)
|
|
end)
|
|
|
|
it("bad position throws an error", function()
|
|
local h = bh.maxHeap()
|
|
h:insert(10)
|
|
assert.has.error(function()
|
|
h:update(0)
|
|
end)
|
|
assert.has.error(function()
|
|
h:update(2)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
it("creates maxHeap with custom greater-than function", function()
|
|
local h = bh.maxHeap(function (a, b)
|
|
return math.abs(a) > math.abs(b)
|
|
end)
|
|
h:insert(1)
|
|
check(h)
|
|
h:insert(-2)
|
|
check(h)
|
|
h:insert(3)
|
|
check(h)
|
|
h:insert(-4)
|
|
check(h)
|
|
h:insert(5)
|
|
check(h)
|
|
assert.equal(5, (h:peek()))
|
|
h:pop()
|
|
check(h)
|
|
assert.equal(-4, (h:peek()))
|
|
end)
|
|
end)
|