186 lines
4.8 KiB
Rust
186 lines
4.8 KiB
Rust
use crate::misc::{Arena, ArenaKey};
|
|
|
|
use super::PriorityQueue;
|
|
|
|
#[derive(Debug)]
|
|
struct FibonacciHeapObject<T> {
|
|
left: ArenaKey,
|
|
right: ArenaKey,
|
|
parent: Option<ArenaKey>,
|
|
child: Option<ArenaKey>,
|
|
rank: usize,
|
|
marked: bool,
|
|
data: T,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct FibonacciHeap<T> {
|
|
arena: Arena<FibonacciHeapObject<T>>,
|
|
min: Option<ArenaKey>,
|
|
update_rank: Vec<Option<ArenaKey>>,
|
|
}
|
|
|
|
pub struct FibonacciHeapHandle(ArenaKey);
|
|
|
|
impl<T> PriorityQueue<T> for FibonacciHeap<T>
|
|
where
|
|
T: std::cmp::Ord,
|
|
{
|
|
type Handle = FibonacciHeapHandle;
|
|
|
|
fn new() -> Self {
|
|
todo!()
|
|
}
|
|
|
|
fn insert(&mut self, item: T) -> Self::Handle {
|
|
let h = self.arena.insert(FibonacciHeapObject {
|
|
left: ArenaKey::default(),
|
|
right: ArenaKey::default(),
|
|
parent: None,
|
|
child: None,
|
|
rank: 0,
|
|
marked: false,
|
|
data: item,
|
|
});
|
|
|
|
self.insert_tree(h);
|
|
|
|
FibonacciHeapHandle(h)
|
|
}
|
|
|
|
fn pop_min(&mut self) -> Option<T> {
|
|
if let Some(k) = self.min.take() {
|
|
let o = self.arena.remove(k);
|
|
|
|
if let Some(child) = o.child {
|
|
let mut p = child;
|
|
loop {
|
|
self.arena.get_mut(&p).parent = None;
|
|
self.arena.get_mut(&p).marked = false;
|
|
let t = self.arena.get(&p).right;
|
|
|
|
self.insert_tree(p);
|
|
|
|
p = t;
|
|
|
|
if p == child {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if o.left != o.right {
|
|
self.arena.get_mut(&o.left).right = o.right;
|
|
self.arena.get_mut(&o.right).left = o.left;
|
|
self.update_min(o.left);
|
|
}
|
|
|
|
Some(o.data)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn decrease_key(&mut self, _handle: &Self::Handle, _f: impl Fn(&mut T)) {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
impl<T> FibonacciHeap<T>
|
|
where
|
|
T: std::cmp::Ord,
|
|
{
|
|
fn insert_tree(&mut self, h: ArenaKey) {
|
|
if let Some(h_min) = self.min {
|
|
let h_last = self.arena.get(&h_min).left;
|
|
|
|
self.arena.get_mut(&h_min).left = h;
|
|
|
|
self.arena.get_mut(&h).left = h_last;
|
|
self.arena.get_mut(&h).right = h_min;
|
|
|
|
self.arena.get_mut(&h_last).right = h;
|
|
|
|
if self.arena.get(&h).data < self.arena.get(&h_min).data {
|
|
self.min = Some(h)
|
|
}
|
|
} else {
|
|
self.arena.get_mut(&h).left = h;
|
|
self.arena.get_mut(&h).right = h;
|
|
|
|
self.min = Some(h);
|
|
}
|
|
}
|
|
|
|
fn update_min(&mut self, mut h: ArenaKey) {
|
|
let h_start = h;
|
|
|
|
loop {
|
|
let next_h = self.arena.get(&h).right;
|
|
|
|
self.add_to_update_rank(h);
|
|
|
|
h = next_h;
|
|
if h == h_start {
|
|
break;
|
|
}
|
|
}
|
|
|
|
let mut prev = None;
|
|
// let mut start = None;
|
|
|
|
for h in &mut self.update_rank {
|
|
if let Some(h) = h.take() {
|
|
if let Some(p) = prev {
|
|
self.arena.get_mut(&h).left = p;
|
|
self.arena.get_mut(&p).right = h;
|
|
} else {
|
|
prev = Some(h);
|
|
// start = Some(h);
|
|
}
|
|
if let Some(m) = self.min {
|
|
if self.arena.get(&h).data < self.arena.get(&m).data {
|
|
self.min = Some(h);
|
|
}
|
|
} else {
|
|
self.min = Some(h);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn add_to_update_rank(&mut self, h: ArenaKey) {
|
|
let rank = self.arena.get(&h).rank;
|
|
|
|
while self.update_rank.len() + 1 < rank {
|
|
self.update_rank.push(None)
|
|
}
|
|
|
|
if let Some(o) = self.update_rank.get_mut(rank).unwrap().take() {
|
|
if let Some(child) = self.arena.get(&h).child {
|
|
let last = self.arena.get(&child).left;
|
|
|
|
self.arena.get_mut(&child).left = h;
|
|
self.arena.get_mut(&last).right = h;
|
|
|
|
self.arena.get_mut(&o).parent = Some(h);
|
|
self.arena.get_mut(&o).marked = false;
|
|
self.arena.get_mut(&o).left = last;
|
|
self.arena.get_mut(&o).right = child;
|
|
} else {
|
|
self.arena.get_mut(&h).child = Some(o);
|
|
|
|
self.arena.get_mut(&o).parent = Some(h);
|
|
self.arena.get_mut(&o).marked = false;
|
|
self.arena.get_mut(&o).left = o;
|
|
self.arena.get_mut(&o).right = o;
|
|
}
|
|
|
|
self.arena.get_mut(&h).rank += 1;
|
|
|
|
self.add_to_update_rank(h);
|
|
} else {
|
|
*self.update_rank.get_mut(rank).unwrap() = Some(h);
|
|
}
|
|
}
|
|
}
|