Initial commit
This commit is contained in:
		
						commit
						7d47a10acf
					
				
					 18 changed files with 1545 additions and 0 deletions
				
			
		
							
								
								
									
										186
									
								
								src/priority_queue/fibonacci_heap.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								src/priority_queue/fibonacci_heap.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,186 @@ | |||
| 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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue