:: PriorityQueue {
@init() {
return {data: []}
}
@len(q) {
return q.data.len
}
@top(q) {
return q.data[0]
}
@push(q,v) {
var ind = q.data.len
q.data.push(v)
loop {
if ind == 0 break
let next = if ind % 2 == 0 {(ind-2) / 2} else {(ind-1) / 2}
if q.data[ind] < q.data[next] {
let tmp = q.data[ind]
q.data[ind] = q.data[next]
q.data[next] = tmp
ind = next
continue
}
else {break}
}
return null
}
@pop(q) {
let v = q.data[0]
if q.data.len == 1 {
q.data.pop()
return v
}
q.data[0] = q.data.pop()
var ind = 0
loop {
if (ind*2)+1 >= q.data.len {break}
if (ind*2)+2 >= q.data.len {
if q.data[ind*2+1] < q.data[ind] {
let tmp = q.data[ind]
q.data[ind] = q.data[ind*2+1]
q.data[ind*2+1] = tmp
ind = ind*2+1
continue
}
else {break}
}
let next = if q.data[ind*2+1] < q.data[ind*2+2] {ind*2+1} else {ind*2+2}
if q.data[next] < q.data[ind] {
let tmp = q.data[ind]
q.data[ind] = q.data[next]
q.data[next] = tmp
ind = next
continue
}
else {break}
}
return v
}
}
var a = PriorityQueue:init()
PriorityQueue:push(a,3)
PriorityQueue:push(a,1)
PriorityQueue:push(a,4)
<:PriorityQueue:pop(a)//1
<:PriorityQueue:pop(a)//3
PriorityQueue:push(a,1)
<:PriorityQueue:len(a)//2
PriorityQueue:push(a,5)
PriorityQueue:push(a,9)
<:PriorityQueue:top(a)//1
PriorityQueue:pop(a)
<:PriorityQueue:top(a)//4