LookAtMySuitBot/js/node_modules/priority-queue/priority-queue.js

164 lines
2.7 KiB
JavaScript
Raw Normal View History

2023-12-24 20:08:39 -05:00
function create (maxLength=1000) {
return {
arr: new Array(maxLength),
length: 0,
maxLength,
}
}
function queue (heap, item, priority) {
if (priority === undefined)
throw new Error('must include priority when queueing')
if (_findIndex(heap, item) >= 0) {
del(heap, item)
}
if (heap.length === heap.maxLength) {
return
}
heap.arr[heap.length] = { item, priority }
heap.length++
_upHeap(heap, heap.length-1)
}
// traverse up the heap from a starting index
//
// heap
// index to start at
function _upHeap (heap, index) {
while (index > 0) {
let parentIdx
if (index % 2 === 0)
parentIdx = (index - 2) / 2
else
parentIdx = (index - 1) / 2
// if the parent is greater than the current node, stop because we've corrected the heap
if (heap.arr[parentIdx].priority >= heap.arr[index].priority)
return
_swap(heap.arr, index, parentIdx)
index = parentIdx
}
}
// get and remove highest priority item from the heap
function dequeue (heap) {
if (heap.length === 0)
return
const max = heap.arr[0].item
heap.length--
heap.arr[0] = heap.arr[heap.length]
_downHeap(heap, 0)
return max
}
// traverse down the heap from a starting index
//
// heap
// index to start at
function _downHeap (heap, index) {
while (index < heap.length) {
const left = index * 2 + 1
const right = index * 2 + 2
let largest = index
if (left < heap.length && heap.arr[left].priority > heap.arr[largest].priority)
largest = left
if (right < heap.length && heap.arr[right].priority > heap.arr[largest].priority)
largest = right
if (largest === index)
return
_swap(heap.arr, index, largest)
index = largest
}
}
function _swap (arr, i, j) {
const tmp = arr[i]
arr[i] = arr[j]
arr[j] = tmp
}
function clear (heap) {
heap.length = 0
}
function isEmpty (heap) {
return heap.length === 0
}
function peek (heap) {
if (!heap.length)
return
return heap.arr[0].item
}
function del (heap, item) {
const ind = _findIndex(heap, item)
if (ind < 0)
throw new Error('key does not exist in priority queue!')
const tmp = heap.arr[ind]
heap.arr[ind] = heap.arr[heap.length-1]
heap.arr[heap.length-1] = tmp
if (heap.arr[ind].priority > heap.arr[heap.length-1].priority)
_upHeap(heap, ind)
else if (heap.arr[ind].priority < heap.arr[heap.length-1].priority)
_downHeap(heap, ind)
heap.length--
}
function _findIndex (heap, item) {
for (let i=0; i < heap.length; i++)
if (heap.arr[i].item === item)
return i
return -1
}
function list (heap) {
if (!heap.length)
return [ ]
const result = [ ]
for (let i=0; i < heap.length; i++)
result[i] = heap.arr[i].item
return result
}
export default { create, queue, dequeue, clear, isEmpty, peek, delete: del, list }