use std::cmp::{Ord, Eq};
use std::hash::Hash;
use ordermap::OrderMap;
#[derive(Clone, Debug)]
pub struct PriorityQueue<I, P>
where I: Hash+Eq{
map: OrderMap<I, P>, heap: Vec<usize>, qp: Vec<usize>, size: usize }
impl<I, P> PriorityQueue<I, P>
where P: Ord,
I: Hash + Eq {
pub fn new() -> PriorityQueue<I, P> {
PriorityQueue{
map: OrderMap::new(),
heap: Vec::new(),
qp: Vec::new(),
size: 0
}
}
pub fn with_capacity(capacity: usize) -> PriorityQueue<I, P> {
PriorityQueue{
map: OrderMap::with_capacity(capacity),
heap: Vec::with_capacity(capacity),
qp: Vec::with_capacity(capacity),
size: 0
}
}
pub fn capacity(&self)->usize {
self.map.capacity()
}
pub fn shrink_to_fit(&mut self){
self.heap.shrink_to_fit();
self.qp.shrink_to_fit();
}
pub fn len(&self) -> usize {
self.size
}
pub fn is_empty(&self) -> bool {
self.size==0
}
pub fn push(&mut self, item: I, priority: P) -> Option<P>{
let r = self.map.insert(item, priority);
let priority = self.map.get_index(self.size).unwrap().1;
let mut i = self.size;
let k = i;
self.qp.push(i);
self.heap.push(0);
while (i > 0) &&
( self.map.get_index(self.heap[parent(i)]).unwrap().1 < &priority ){
self.heap[i] = self.heap[parent(i)];
self.qp[self.heap[i]] = i;
i = parent(i);
}
self.heap[i] = k;
self.qp[k] = i;
self.size += 1;
r
}
pub fn peek(&self) -> Option<(&I, &P)>{
self.map.get_index(self.heap[0])
}
pub fn peek_mut(&mut self) -> Option<(&mut I, &P)> {
self.map.get_index_mut(self.heap[0])
.map(|pair| (pair.0, &(*pair.1)))
}
pub fn pop(&mut self) -> Option<(I, P)> {
if self.size == 0 {
return None;
}
let result = self.swap_remove();
if self.size > 0 {
self.heapify(0);
}
result
}
fn swap_remove(&mut self) -> Option<(I, P)>{
let head = self.heap.swap_remove(0);
self.size -= 1;
if self.size == 0 {
self.qp.pop();
return self.map.swap_remove_index(head);
}
self.qp[self.heap[0]] = 0;
self.qp.swap_remove(head);
if head < self.size {
self.heap[self.qp[head]] = head;
}
self.map.swap_remove_index(head)
}
fn swap(&mut self, a: usize, b:usize) {
let (i, j) = (self.heap[a], self.heap[b]);
self.heap.swap(a, b);
self.qp.swap(i, j);
}
fn heapify(&mut self, i: usize) {
let (mut l, mut r) = (left(i), right(i));
let mut i = i;
let mut largest;
if l < self.size &&
self.map.get_index(self.heap[l]).unwrap().1 >
self.map.get_index(self.heap[i]).unwrap().1
{
largest = l;
} else {
largest = i;
}
if r < self.size &&
self.map.get_index(self.heap[r]).unwrap().1 >
self.map.get_index(self.heap[largest]).unwrap().1
{
largest = r;
}
while largest != i {
self.swap(i, largest);
i = largest;
l = left(i);
r = right(i);
if l < self.size &&
self.map.get_index(self.heap[l]).unwrap().1 >
self.map.get_index(self.heap[i]).unwrap().1
{
largest = l;
}
else {
largest = i;
}
if r < self.size &&
self.map.get_index(self.heap[r]).unwrap().1 >
self.map.get_index(self.heap[largest]).unwrap().1
{
largest = r;
}
}
}
}
#[inline]
fn left(i:usize) -> usize {
(i*2) +1
}
#[inline]
fn right(i:usize) -> usize {
(i*2) +2
}
#[inline]
fn parent(i:usize) -> usize{
(i-1) /2
}