mod orientation;
#[cfg(test)]
mod unit_test;
pub use orientation::Orientation;
use std::collections::BinaryHeap;
use std::mem::replace;
#[derive(Debug)]
pub struct BinaryHeapQueue<T> {
heap: BinaryHeap<T>,
}
impl<T: Ord> Default for BinaryHeapQueue<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Ord> BinaryHeapQueue<T> {
pub fn new() -> Self {
Self {
heap: BinaryHeap::<T>::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
heap: BinaryHeap::<T>::with_capacity(capacity),
}
}
pub fn is_empty(&self) -> bool {
self.heap.is_empty()
}
pub fn len(&self) -> usize {
self.heap.len()
}
pub fn insert(&mut self, key: T) {
self.heap.push(key)
}
pub fn delete(&mut self) -> Option<T> {
self.heap.pop()
}
pub fn extremum(&self) -> Option<&T> {
self.heap.peek()
}
}
#[derive(Debug, Default, Clone)]
pub struct PriorityQueue<T> {
vec: Vec<Option<T>>,
kind: Orientation,
n: usize,
}
impl<T> PriorityQueue<T> {
pub fn with_capacity(capacity: usize, k: Orientation) -> Self {
if capacity > 0 {
let mut vector = Vec::with_capacity(capacity + 1);
for _ in 0..capacity + 1 {
vector.push(None);
}
Self {
vec: vector,
kind: k,
n: 1,
}
} else {
panic!("capacity shoul be > 0");
}
}
pub fn is_empty(&self) -> bool {
self.n == 1
}
pub fn len(&self) -> usize {
self.n - 1
}
pub fn extremum(&self) -> Option<&T> {
self.vec[1].as_ref()
}
fn double(&mut self) {
let mut vector = Vec::with_capacity(self.vec.len());
for _ in 0..self.vec.len() {
vector.push(None);
}
self.vec.append(&mut vector);
}
fn halve(&mut self) {
self.vec.truncate(self.vec.len() / 2);
}
}
impl<T: Ord + Clone> PriorityQueue<T> {
fn swim(&mut self, mut k: usize) {
match self.kind {
Orientation::Max => {
while k > 1 && self.vec[k] > self.vec[k / 2] {
let val = self.vec[k].clone();
self.vec[k] = replace(&mut self.vec[k / 2], val);
k /= 2;
}
}
Orientation::Min => {
while k > 1 && self.vec[k] < self.vec[k / 2] {
let val = self.vec[k].clone();
self.vec[k] = replace(&mut self.vec[k / 2], val);
k /= 2;
}
}
}
}
pub fn insert(&mut self, key: T) {
if self.n < self.vec.len() {
self.vec[self.n] = Some(key);
self.swim(self.n);
self.n += 1;
if self.n == self.vec.len() {
self.double();
}
} else {
panic!("cannot push, stack is full or has capacity 0");
}
}
fn sink(&mut self, mut k: usize, n: usize) {
if self.is_empty() {
panic!("cannot sink data, queue is empty.")
} else {
match self.kind {
Orientation::Max => {
while 2 * k < n {
let mut j = 2 * k;
if j < n - 1 && self.vec[j] < self.vec[j + 1] {
j += 1;
}
if self.vec[k] >= self.vec[j] {
break;
}
let val = self.vec[k].clone();
self.vec[k] = replace(&mut self.vec[j], val);
k = j;
}
}
Orientation::Min => {
while 2 * k < n {
let mut j = 2 * k;
if j < n - 1 && self.vec[j] > self.vec[j + 1] {
j += 1;
}
if self.vec[k] <= self.vec[j] {
break;
}
let val = self.vec[k].clone();
self.vec[k] = replace(&mut self.vec[j], val);
k = j;
}
}
}
}
}
pub fn delete(&mut self) -> Option<T> {
if self.is_empty() {
panic!("cannot delete, queue is empty");
} else {
let res = self.vec[1].clone();
self.vec[1] = replace(&mut self.vec[self.n - 1], None);
self.sink(1, self.n);
self.n -= 1;
if self.n <= self.vec.len() / 4 {
self.halve();
}
res
}
}
}