use std::cmp::{Ord, Eq};
use std::hash::Hash;
use std::borrow::Borrow;
use std::iter::Iterator;
use ordermap::OrderMap;
#[derive(Clone, Debug)]
pub struct PriorityQueue<I, P>
where I: Hash+Eq{
map: OrderMap<I, Option<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 iter(&self) {
}
pub fn peek(&self) -> Option<(&I, &P)>{
self.map.get_index(self.heap[0]).map(|(k, v)| (k, v.as_ref().unwrap()))
}
pub fn peek_mut(&mut self) -> Option<(&mut I, &P)> {
self.map.get_index_mut(self.heap[0])
.map(|(k, v)| (k, v.as_ref().unwrap()))
}
pub fn capacity(&self)->usize {
self.map.capacity()
}
pub fn reserve(&mut self, additional: usize){
self.map.reserve(additional);
self.heap.reserve(additional);
self.qp.reserve(additional);
}
pub fn shrink_to_fit(&mut self){
self.heap.shrink_to_fit();
self.qp.shrink_to_fit();
}
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
}
pub fn push(&mut self, item: I, priority: P) -> Option<P>{
let mut pos;
let oldp;
if self.map.contains_key(&item){
{
let (index, old_item, p) =
self.map.get_pair_index_mut(&item).unwrap();
*old_item = item;
oldp = p.take();
*p = Some(priority);
pos = self.qp[index];
}
let tmp = self.heap[pos];
while (pos > 0) &&
(self.map.get_index(self.heap[parent(pos)]).unwrap().1 <
self.map.get_index(self.heap[pos]).unwrap().1)
{
self.heap[pos] = self.heap[parent(pos)];
self.qp[self.heap[pos]] = pos;
pos = parent(pos);
}
self.heap[pos] = tmp;
self.qp[tmp] = pos;
self.heapify(pos);
return oldp;
}
self.map.insert(item, Some(priority)).map(|o| o.unwrap());
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;
None
}
pub fn change_priority<Q: ?Sized>(&mut self, item: &Q, new_priority: P)
-> Option<P>
where I: Borrow<Q>,
Q:Eq + Hash
{
let mut pos = 0;
let r =
if let Some((index, _, p))= self.map.get_pair_index_mut(item) {
let oldp = p.take();
*p = Some(new_priority);
pos = index;
oldp
} else {
None
};
if r.is_some() {
let tmp = self.heap[pos];
while (pos > 0) &&
(self.map.get_index(self.heap[parent(pos)]).unwrap().1 <
self.map.get_index(self.heap[pos]).unwrap().1)
{
self.heap[pos] = self.heap[parent(pos)];
self.qp[self.heap[pos]] = pos;
pos = parent(pos);
}
self.heap[pos] = tmp;
self.qp[tmp] = pos;
self.heapify(pos);
}
r
}
pub fn change_priority_by<Q: ?Sized, F>
(&mut self, item: &Q, priority_setter: F)
where I: Borrow<Q>,
Q: Eq + Hash,
F: FnOnce(P) -> P
{
let mut pos = 0;
let mut found = false;
if let Some((index, _, p))= self.map.get_pair_index_mut(item) {
let oldp = p.take().unwrap();
*p = Some(priority_setter(oldp));
pos = index;
found = true;
}
if found {
let tmp = self.heap[pos];
while (pos > 0) &&
(self.map.get_index(self.heap[parent(pos)]).unwrap().1 <
self.map.get_index(self.heap[pos]).unwrap().1)
{
self.heap[pos] = self.heap[parent(pos)];
self.qp[self.heap[pos]] = pos;
pos = parent(pos);
}
self.heap[pos] = tmp;
self.qp[tmp] = pos;
self.heapify(pos);
}
}
pub fn get_priority<Q: ?Sized>(&self, item: &Q) -> Option<&P>
where I: Borrow<Q>,
Q: Eq + Hash
{
self.map.get(item).map(|o| o.as_ref().unwrap())
}
pub fn get<Q>(&self, item: &Q) -> Option<(&I, &P)>
where I: Borrow<Q>,
Q: Eq + Hash
{
self.map.get_pair(item).map(|(k, v)| (k, v.as_ref().unwrap()))
}
pub fn get_mut<Q>(&mut self, item: &Q) -> Option<(&mut I, &P)>
where I: Borrow<Q>,
Q: Eq + Hash
{
self.map.get_pair_mut(item).map(|(k, v)| (k, v.as_ref().unwrap()))
}
pub fn into_vec(self) -> Vec<I> {
self.map.into_iter().map(|(i, _)| i).collect()
}
pub fn into_sorted_vec(mut self) -> Vec<I> {
let mut res = Vec::with_capacity(self.size);
while let Some((i, _)) = self.pop() {
res.push(i);
}
res
}
pub fn len(&self) -> usize {
self.size
}
pub fn is_empty(&self) -> bool {
self.size==0
}
pub fn clear(&mut self){
self.heap.clear();
self.qp.clear();
self.map.clear();
self.size=0;
}
pub fn append(&mut self, other: &mut Self) {
if other.size > self.size {
::std::mem::swap(self, other);
}
if other.size == 0 {
return;
}
let drain = other.map.drain(..);
for (k, v) in drain {
if !self.map.contains_key(&k) {
let i = self.size;
self.map.insert(k, v);
self.heap.push(i);
self.qp.push(i);
self.size += 1;
}
}
other.heap.clear();
other.qp.clear();
self.heap_build();
}
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)
.map(|(i, o)| (i, o.unwrap()));
}
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)
.map(|(i, o)| (i, o.unwrap()))
}
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;
}
}
}
fn heap_build(&mut self){
for i in (0..parent(self.size)).rev(){
self.heapify(i);
}
}
}
impl<I, P> From<Vec<(I, P)>> for PriorityQueue<I, P>
where I: Hash+Eq,
P: Ord {
fn from(vec: Vec<(I, P)>) -> PriorityQueue<I, P>{
let mut pq = PriorityQueue::with_capacity(vec.len());
let mut i=0;
for (item, priority) in vec {
if !pq.map.contains_key(&item) {
pq.map.insert(item, Some(priority));
pq.qp.push(i);
pq.heap.push(i);
i+=1;
}
}
pq.size=i;
pq.heap_build();
pq
}
}
impl<I, P> ::std::iter::FromIterator<(I, P)> for PriorityQueue<I, P>
where I: Hash+Eq,
P: Ord {
fn from_iter<IT>(iter: IT) -> PriorityQueue<I, P>
where IT: IntoIterator<Item = (I, P)>{
let iter = iter.into_iter();
let (min, max) = iter.size_hint();
let mut pq =
if let Some(max) = max {
PriorityQueue::with_capacity(max)
} else if min != 0 {
PriorityQueue::with_capacity(min)
} else {
PriorityQueue::new()
};
for (item, priority) in iter {
if !pq.map.contains_key(&item){
pq.map.insert(item, Some(priority));
pq.qp.push(pq.size);
pq.heap.push(pq.size);
pq.size+=1;
} else {
let (old_item, old_priority) =
pq.map.get_pair_mut(&item).unwrap();
*old_item = item;
*old_priority = Some(priority);
}
}
pq.heap_build();
pq
}
}
#[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
}