#![allow(dead_code)]
#[derive(Debug, Clone)]
struct PairingNode<K: Ord + Clone, V: Clone> {
key: K,
val: V,
children: Vec<PairingNode<K, V>>,
}
impl<K: Ord + Clone, V: Clone> PairingNode<K, V> {
fn new(key: K, val: V) -> Self {
PairingNode {
key,
val,
children: vec![],
}
}
fn merge(self, other: PairingNode<K, V>) -> PairingNode<K, V> {
if self.key <= other.key {
let mut root = self;
root.children.push(other);
root
} else {
let mut root = other;
root.children.push(self);
root
}
}
fn two_pass_merge(mut children: Vec<PairingNode<K, V>>) -> Option<PairingNode<K, V>> {
if children.is_empty() {
return None;
}
let mut pairs: Vec<PairingNode<K, V>> = Vec::new();
while children.len() >= 2 {
let b = children.remove(0);
let a = children.remove(0);
pairs.push(a.merge(b));
}
if let Some(rem) = children.into_iter().next() {
pairs.push(rem);
}
pairs.into_iter().reduce(|acc, p| p.merge(acc))
}
}
pub struct PairingHeap<K: Ord + Clone, V: Clone> {
root: Option<PairingNode<K, V>>,
count: usize,
}
impl<K: Ord + Clone, V: Clone> PairingHeap<K, V> {
pub fn new() -> Self {
PairingHeap {
root: None,
count: 0,
}
}
pub fn insert(&mut self, key: K, val: V) {
let node = PairingNode::new(key, val);
self.root = match self.root.take() {
None => Some(node),
Some(r) => Some(r.merge(node)),
};
self.count += 1;
}
pub fn peek_min(&self) -> Option<(&K, &V)> {
self.root.as_ref().map(|r| (&r.key, &r.val))
}
pub fn extract_min(&mut self) -> Option<(K, V)> {
let root = self.root.take()?;
self.root = PairingNode::two_pass_merge(root.children);
self.count = self.count.saturating_sub(1);
Some((root.key, root.val))
}
pub fn len(&self) -> usize {
self.count
}
pub fn is_empty(&self) -> bool {
self.count == 0
}
pub fn merge(&mut self, other: PairingHeap<K, V>) {
self.count += other.count;
self.root = match (self.root.take(), other.root) {
(None, r) => r,
(l, None) => l,
(Some(l), Some(r)) => Some(l.merge(r)),
};
}
}
impl<K: Ord + Clone, V: Clone> Default for PairingHeap<K, V> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_insert_and_peek() {
let mut h: PairingHeap<u32, u32> = PairingHeap::new();
h.insert(5, 50);
h.insert(2, 20);
let (k, _) = h.peek_min().expect("should succeed");
assert_eq!(*k, 2 );
}
#[test]
fn test_extract_min() {
let mut h: PairingHeap<u32, u32> = PairingHeap::new();
h.insert(4, 40);
h.insert(1, 10);
let (k, v) = h.extract_min().expect("should succeed");
assert_eq!(k, 1 );
assert_eq!(v, 10);
}
#[test]
fn test_len_tracks() {
let mut h: PairingHeap<u32, u32> = PairingHeap::new();
h.insert(1, 1);
h.insert(2, 2);
assert_eq!(h.len(), 2);
}
#[test]
fn test_is_empty() {
let h: PairingHeap<u32, u32> = PairingHeap::new();
assert!(h.is_empty());
}
#[test]
fn test_extract_all_sorted() {
let mut h: PairingHeap<u32, u32> = PairingHeap::new();
for v in [3u32, 1, 4, 1, 5, 9, 2] {
h.insert(v, v);
}
let mut last = 0u32;
while let Some((k, _)) = h.extract_min() {
assert!(k >= last );
last = k;
}
}
#[test]
fn test_merge_heaps() {
let mut a: PairingHeap<u32, u32> = PairingHeap::new();
let mut b: PairingHeap<u32, u32> = PairingHeap::new();
a.insert(10, 10);
b.insert(5, 5);
a.merge(b);
let (k, _) = a.peek_min().expect("should succeed");
assert_eq!(*k, 5 );
}
#[test]
fn test_empty_extract() {
let mut h: PairingHeap<u32, u32> = PairingHeap::new();
assert!(h.extract_min().is_none() );
}
#[test]
fn test_default() {
let h: PairingHeap<u32, u32> = PairingHeap::default();
assert!(h.is_empty());
}
#[test]
fn test_single_element() {
let mut h: PairingHeap<u32, u32> = PairingHeap::new();
h.insert(42, 420);
assert_eq!(h.extract_min(), Some((42, 420)) );
assert!(h.is_empty());
}
}