use super::heap::Heap;
use crate::{positions::none::HeapPositionsNone, PriorityQueue};
pub type BinaryHeap<N, K> = DaryHeap<N, K, 2>;
pub type QuaternaryHeap<N, K> = DaryHeap<N, K, 4>;
#[derive(Clone, Debug)]
pub struct DaryHeap<N, K, const D: usize = 2>
where
N: Clone,
K: PartialOrd + Clone,
{
heap: Heap<N, K, HeapPositionsNone, D>,
}
impl<N, K, const D: usize> Default for DaryHeap<N, K, D>
where
N: Clone,
K: PartialOrd + Clone,
{
fn default() -> Self {
Self {
heap: Heap::new(None, HeapPositionsNone),
}
}
}
impl<N, K, const D: usize> DaryHeap<N, K, D>
where
N: Clone,
K: PartialOrd + Clone,
{
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
heap: Heap::new(Some(capacity), HeapPositionsNone),
}
}
pub const fn d() -> usize {
D
}
pub fn as_slice(&self) -> &[(N, K)] {
self.heap.as_slice()
}
}
impl<N, K, const D: usize> PriorityQueue<N, K> for DaryHeap<N, K, D>
where
N: Clone,
K: PartialOrd + Clone,
{
type NodeKey<'a>
= &'a (N, K)
where
Self: 'a,
N: 'a,
K: 'a;
type Iter<'a>
= core::slice::Iter<'a, (N, K)>
where
Self: 'a,
N: 'a,
K: 'a;
#[inline(always)]
fn len(&self) -> usize {
self.heap.len()
}
#[inline(always)]
fn capacity(&self) -> usize {
self.heap.capacity()
}
fn peek(&self) -> Option<&(N, K)> {
self.heap.peek()
}
fn clear(&mut self) {
self.heap.clear()
}
#[inline(always)]
fn pop(&mut self) -> Option<(N, K)> {
self.heap.pop()
}
#[inline(always)]
fn pop_node(&mut self) -> Option<N> {
self.heap.pop_node()
}
#[inline(always)]
fn pop_key(&mut self) -> Option<K> {
self.heap.pop_key()
}
#[inline(always)]
fn push(&mut self, node: N, key: K) {
self.heap.push(node, key)
}
#[inline(always)]
fn push_then_pop(&mut self, node: N, key: K) -> (N, K) {
self.heap.push_then_pop(node, key)
}
fn iter(&self) -> Self::Iter<'_> {
self.as_slice().iter()
}
}