mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Co-authored-by: silicons <2003111+silicons@users.noreply.github.com> Co-authored-by: silicons <no@you.cat>
90 lines
2.2 KiB
Plaintext
90 lines
2.2 KiB
Plaintext
//* This file is explicitly licensed under the MIT license. *//
|
|
//* Copyright (c) 2023 Citadel Station developers. *//
|
|
|
|
/**
|
|
* An array-backed priority queue.
|
|
*
|
|
* The "front" of the queue is popped first; check comparators.dm for what this means.
|
|
*/
|
|
/datum/priority_queue
|
|
/// comparaison function
|
|
var/procpath/comparison
|
|
/// internal array
|
|
var/list/array = list()
|
|
|
|
/datum/priority_queue/New(cmp)
|
|
src.comparison = cmp
|
|
array = list()
|
|
|
|
/datum/priority_queue/proc/is_empty()
|
|
return length(array) == 0
|
|
|
|
/datum/priority_queue/proc/enqueue(entry)
|
|
array += entry
|
|
bubble_up(length(array))
|
|
|
|
/datum/priority_queue/proc/dequeue()
|
|
if(length(array) == 0)
|
|
return null
|
|
. = array[1]
|
|
array.Swap(1, length(array))
|
|
--array.len
|
|
bubble_down(1)
|
|
|
|
/datum/priority_queue/proc/peek()
|
|
return length(array)? array[1] : null
|
|
|
|
// todo: define this
|
|
/datum/priority_queue/proc/bubble_up(index)
|
|
while(index >= 2 && call(comparison)(array[index], array[index / 2]) < 0)
|
|
array.Swap(index, index / 2)
|
|
index /= 2
|
|
|
|
// todo: define this
|
|
/datum/priority_queue/proc/bubble_down(index)
|
|
var/length = length(array)
|
|
var/next = index * 2
|
|
while(next <= length)
|
|
// left always exists, right doesn't necessarily exist
|
|
if(call(comparison)(array[next], array[index]) < 0)
|
|
if(next < length && call(comparison)(array[next], array[next + 1]) > 0)
|
|
array.Swap(index, next + 1)
|
|
index = next + 1
|
|
else
|
|
array.Swap(index, next)
|
|
index = next
|
|
else if(next < length && call(comparison)(array[next + 1], array[index]) < 0)
|
|
array.Swap(index, next + 1)
|
|
index = next + 1
|
|
else
|
|
break
|
|
next = index * 2
|
|
|
|
/**
|
|
* returns copy of list of entries in no particular order
|
|
*/
|
|
/datum/priority_queue/proc/flattened()
|
|
return array.Copy()
|
|
|
|
/datum/priority_queue/proc/remove_index(index)
|
|
var/length = length(array)
|
|
if(!index || index > length)
|
|
return
|
|
if(index == length)
|
|
. = array[index]
|
|
--array.len
|
|
return
|
|
. = array[index]
|
|
array.Swap(index, length)
|
|
--array.len
|
|
bubble_down(index)
|
|
|
|
/datum/priority_queue/proc/find(entry)
|
|
return array.Find(entry)
|
|
|
|
/datum/priority_queue/proc/remove_entry(entry)
|
|
return remove_index(array.Find(entry))
|
|
|
|
/datum/priority_queue/proc/size()
|
|
return length(array)
|