use crate::misc::{Arena, ArenaKey}; use super::PriorityQueue; #[derive(Debug)] struct FibonacciHeapObject { left: ArenaKey, right: ArenaKey, parent: Option, child: Option, rank: usize, marked: bool, data: T, } #[derive(Debug)] pub struct FibonacciHeap { arena: Arena>, min: Option, update_rank: Vec>, } pub struct FibonacciHeapHandle(ArenaKey); impl PriorityQueue for FibonacciHeap 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 { 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 FibonacciHeap 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); } } }