62 lines
1.5 KiB
GDScript3
Raw Permalink Normal View History

2025-01-11 00:25:52 +01:00
## Heap queue algorithm (a.k.a. priority queue).
## See [url]https://github.com/python/cpython/blob/3.10/Lib/heapq.py[/url]
func heappush(heap : Array, item):
heap.append(item)
_siftdown(heap, 0, len(heap) - 1)
func heappop(heap : Array):
var lastelt = heap.pop_back()
if heap != null and not heap.is_empty():
var returnitem = heap[0]
heap[0] = lastelt
_siftup(heap, 0)
return returnitem
return lastelt
func heapreplace(heap : Array, item):
var returnitem = heap[0]
heap[0] = item
_siftup(heap, 0)
return returnitem
func heappushpop(heap : Array, item):
if heap != null and not heap.is_empty() and GDRx.lt(heap[0], item):
var item_tmp = heap[0]
heap[0] = item
item = item_tmp
_siftup(heap, 0)
return item
func heapify(x : Array):
var n = len(x)
var rang_ = range(int(n / 2.0)) ; rang_.reverse()
for i in rang_:
_siftup(x, i)
func _siftdown(heap : Array, startpos, pos):
var newitem = heap[pos]
while pos > startpos:
var parentpos = (pos - 1) >> 1
var parent = heap[parentpos]
if GDRx.lt(newitem, parent):
pos = parentpos
continue
break
heap[pos] = newitem
func _siftup(heap : Array, pos):
var endpos = len(heap)
var startpos = pos
var newitem = heap[pos]
var childpos = 2 * pos + 1
while childpos < endpos:
var rightpos = childpos + 1
if rightpos < endpos and not GDRx.lt(heap[childpos], heap[rightpos]):
childpos = rightpos
heap[pos] = heap[childpos]
pos = childpos
childpos = 2 * pos + 1
heap[pos] = newitem
_siftdown(heap, startpos, pos)