99 lines
2.8 KiB
Rust
99 lines
2.8 KiB
Rust
pub mod binary_heap;
|
|
pub mod fibonacci_heap;
|
|
|
|
pub trait PriorityQueue<Item>
|
|
where
|
|
Item: PartialOrd,
|
|
{
|
|
type Handle;
|
|
fn new() -> Self;
|
|
// fn with_capacity() -> Self {
|
|
// Self::new()
|
|
// }
|
|
|
|
fn insert(&mut self, item: Item) -> Self::Handle;
|
|
fn pop_min(&mut self) -> Option<Item>;
|
|
fn decrease_key(&mut self, handle: &Self::Handle, f: impl Fn(&mut Item));
|
|
fn increase_key(&mut self, handle: &Self::Handle, f: impl Fn(&mut Item));
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::PriorityQueue;
|
|
use super::binary_heap::{BinaryHeap, FastBinaryHeap};
|
|
use super::fibonacci_heap::FibonacciHeap;
|
|
|
|
macro_rules! test_generics {
|
|
($($fun_mul:ident )+ ; $gen:ident $($gen_mul:ident)+) => {
|
|
test_generics!(@internal_mod $($fun_mul )*; $gen);
|
|
test_generics!($($fun_mul )*; $($gen_mul )*);
|
|
};
|
|
($($fun_mul:ident )+ ;$gen:ident) => {
|
|
test_generics!(@internal_mod $($fun_mul )*; $gen);
|
|
};
|
|
(@internal_mod $($fun_mul:ident )+; $gen:ident) => {
|
|
#[allow(non_snake_case)]
|
|
mod $gen {
|
|
test_generics!(@internal $($fun_mul )*; $gen);
|
|
}
|
|
};
|
|
(@internal $fun:ident $($fun_mul:ident )+; $gen:ident) => {
|
|
test_generics!(@internal $fun; $gen);
|
|
test_generics!(@internal $($fun_mul )*; $gen);
|
|
};
|
|
(@internal $fun:ident; $gen:ident) => {
|
|
|
|
#[test]
|
|
fn $fun() {
|
|
super::super::$fun::<super::super::$gen<usize>>();
|
|
}
|
|
}
|
|
}
|
|
|
|
mod test_macro {
|
|
test_generics!(basic_generic decrease_key_generic; BinaryHeap FastBinaryHeap FibonacciHeap);
|
|
}
|
|
|
|
fn basic_generic<T: PriorityQueue<usize>>() {
|
|
let mut q = T::new();
|
|
|
|
q.insert(2);
|
|
q.insert(3);
|
|
q.insert(10);
|
|
q.insert(12);
|
|
q.insert(9);
|
|
q.insert(6);
|
|
q.insert(4);
|
|
q.insert(5);
|
|
q.insert(8);
|
|
q.insert(7);
|
|
q.insert(11);
|
|
q.insert(1);
|
|
|
|
assert_eq!(q.pop_min(), Some(1));
|
|
assert_eq!(q.pop_min(), Some(2));
|
|
assert_eq!(q.pop_min(), Some(3));
|
|
assert_eq!(q.pop_min(), Some(4));
|
|
assert_eq!(q.pop_min(), Some(5));
|
|
assert_eq!(q.pop_min(), Some(6));
|
|
assert_eq!(q.pop_min(), Some(7));
|
|
assert_eq!(q.pop_min(), Some(8));
|
|
assert_eq!(q.pop_min(), Some(9));
|
|
assert_eq!(q.pop_min(), Some(10));
|
|
assert_eq!(q.pop_min(), Some(11));
|
|
assert_eq!(q.pop_min(), Some(12));
|
|
assert_eq!(q.pop_min(), None);
|
|
}
|
|
|
|
fn decrease_key_generic<T: PriorityQueue<usize>>() {
|
|
let mut q = T::new();
|
|
|
|
q.insert(4);
|
|
let h = q.insert(5);
|
|
|
|
q.decrease_key(&h, |i| *i -= 3);
|
|
|
|
assert_eq!(q.pop_min(), Some(2));
|
|
assert_eq!(q.pop_min(), Some(4));
|
|
}
|
|
}
|