1use std::ptr::NonNull;
2
3type RootLink<T> = NonNull<RootNode<T>>;
4type Link<T> = NonNull<Node<T>>;
5
6pub struct FibonacciHeap<T> {
7 len: usize,
8 max: Option<RootLink<T>>,
9 ends: Option<(RootLink<T>, RootLink<T>)>,
10}
11
12struct RootNode<T> {
13 root: Link<T>,
14 next_root: Option<RootLink<T>>,
15}
16
17struct Node<T> {
18 val: T,
19 parent: Option<Link<T>>,
20 neighbor: (Link<T>, Link<T>),
23 any_child: Option<Link<T>>,
24 order: usize,
25 cut: bool,
26 root: Option<RootLink<T>>,
27}
28
29pub struct NodeRef<T> {
30 node: Link<T>,
31}
32
33struct Bucket<T> {
34 bucket: Vec<Option<RootLink<T>>>,
35}
36
37impl<T: Ord> FibonacciHeap<T> {
38 pub fn new() -> Self { Self { len: 0, max: None, ends: None } }
39
40 pub fn len(&self) -> usize { self.len }
41 pub fn is_empty(&self) -> bool { self.len == 0 }
42
43 pub fn push(&mut self, elt: T) -> NodeRef<T> {
44 self.len += 1;
45 let new = Node::new(elt);
46 self.push_root(RootNode::new(new));
47 NodeRef::new(new)
48 }
49
50 pub fn pop(&mut self) -> Option<T> {
51 let root = self.max.take()?;
52 self.len -= 1;
53 while let Some(child) =
54 unsafe { Node::pop_child((*root.as_ptr()).root) }
55 {
56 self.push_root(RootNode::new(child));
58 }
59 self.coalesce();
62 Some(RootNode::take(root))
63 }
64
65 pub fn meld(&mut self, mut other: Self) {
66 self.len += other.len;
67 if let Some((other_first, other_last)) = other.ends.take() {
68 if let Some((first, last)) = self.ends {
69 RootNode::append(last, other_first);
70 self.ends = Some((first, other_last));
71 } else {
72 self.ends = other.ends;
73 }
74 }
75 if let Some(other_max) = other.max.take() {
76 self.push_root(other_max);
77 }
78 }
79
80 pub unsafe fn urge(&mut self, handle: NodeRef<T>, new: T) -> bool {
81 let node = handle.node;
82 unsafe {
83 if (*node.as_ptr()).val >= new {
84 return false;
85 }
86
87 (*node.as_ptr()).val = new;
88 if !Node::is_heapified(node) {
89 let mut node = Some(node);
90 while let Some(cur) = node {
91 node = Node::orphan(cur);
92 self.push_root(RootNode::new(cur));
93 }
94 }
95
96 if let (Some(old), Some(new)) = (self.max, (*node.as_ptr()).root) {
97 RootNode::challenge(old, new);
98 }
99 }
100 true
101 }
102
103 fn push_root(&mut self, new: RootLink<T>) {
104 if let Some(old) = self.max {
105 RootNode::challenge(old, new);
106 if let Some((first, last)) = self.ends {
107 RootNode::append(last, new);
108 self.ends = Some((first, new));
109 } else {
110 self.ends = Some((new, new));
111 }
112 } else {
113 self.max = Some(new);
114 }
115 }
116
117 fn coalesce(&mut self) {
118 let mut bucket = Bucket::new();
119
120 if let Some(max) = self.max.take() {
121 RootNode::isolate(max);
122 bucket.push(max);
123 }
124 if let Some((first, _)) = self.ends.take() {
125 let mut root = Some(first);
126 while let Some(cur) = root {
127 unsafe {
128 let ptr = cur.as_ptr();
129 root = (*ptr).next_root;
130 }
131 RootNode::isolate(cur);
132 bucket.push(cur);
133 }
134 }
135
136 for root in bucket.take() {
137 self.push_root(root);
138 }
139 }
140}
141
142impl<T> Drop for FibonacciHeap<T> {
143 fn drop(&mut self) {
144 if let Some(max) = self.max.take() {
145 RootNode::drop(max);
146 }
147 if let Some((first, _)) = self.ends.take() {
148 let mut cur = Some(first);
149 while let Some(root) = cur {
150 cur = unsafe { (*root.as_ptr()).next_root };
151 RootNode::drop(root);
152 }
153 }
154 }
155}
156
157impl<T> RootNode<T> {
158 pub fn new(node: Link<T>) -> RootLink<T> {
159 let root = Self { root: node, next_root: None };
160 let root = NonNull::from(Box::leak(Box::new(root)));
161 unsafe { (*node.as_ptr()).root = Some(root) };
162 root
163 }
164
165 pub fn append(fst: RootLink<T>, snd: RootLink<T>) {
166 unsafe {
167 debug_assert!((*fst.as_ptr()).next_root.is_none());
168 (*fst.as_ptr()).next_root = Some(snd);
169 }
170 }
171
172 pub fn challenge(old: RootLink<T>, new: RootLink<T>)
173 where
174 T: Ord,
175 {
176 if old == new {
177 return;
178 }
179 if Self::val(old) < Self::val(new) {
180 let old_ptr = old.as_ptr();
181 let new_ptr = new.as_ptr();
182 unsafe {
183 debug_assert!((*(*old_ptr).root.as_ptr()).parent.is_none());
184 debug_assert!((*(*new_ptr).root.as_ptr()).parent.is_none());
185 std::mem::swap(
186 &mut (*(*old_ptr).root.as_ptr()).root,
187 &mut (*(*new_ptr).root.as_ptr()).root,
188 );
189 std::mem::swap(&mut (*old_ptr).root, &mut (*new_ptr).root);
190 }
191 }
192 }
193
194 fn val<'a>(this: RootLink<T>) -> &'a T {
195 unsafe { &(*(*this.as_ptr()).root.as_ptr()).val }
196 }
197 fn order(this: RootLink<T>) -> usize {
198 unsafe { (*(*this.as_ptr()).root.as_ptr()).order }
199 }
200 fn is_isolated_root(this: RootLink<T>) -> bool {
201 let ptr = this.as_ptr();
202 unsafe {
203 (*ptr).next_root.is_none()
204 && (*(*ptr).root.as_ptr()).parent.is_none()
205 && (*ptr).root == (*(*ptr).root.as_ptr()).neighbor.0
206 }
207 }
208
209 fn isolate(this: RootLink<T>) {
210 let ptr = this.as_ptr();
211 unsafe {
212 (*ptr).next_root.take();
213 (*(*ptr).root.as_ptr()).parent.take();
214 Node::init_siblings((*ptr).root);
215 }
216 }
217
218 fn fuse(par: RootLink<T>, child: RootLink<T>) -> RootLink<T>
219 where
220 T: Ord,
221 {
222 Self::precheck_fuse(par, child);
223 let (greater, less) = if Self::val(par) > Self::val(child) {
224 (par, child)
225 } else {
226 (child, par)
227 };
228 unsafe {
229 Node::push_child((*greater.as_ptr()).root, (*less.as_ptr()).root);
230 drop(Box::from_raw(less.as_ptr()));
231 greater
232 }
233 }
234
235 fn precheck_fuse(par: RootLink<T>, child: RootLink<T>) {
236 debug_assert_eq!(Self::order(par), Self::order(child));
237 debug_assert!(Self::is_isolated_root(par));
238 debug_assert!(Self::is_isolated_root(child));
239 }
240
241 fn take(this: RootLink<T>) -> T {
242 let ptr = this.as_ptr();
243 let node = unsafe { Box::from_raw((*ptr).root.as_ptr()) };
244 let res = node.val;
245 unsafe { drop(Box::from_raw(ptr)) };
246 res
247 }
248}
249
250impl<T> RootNode<T> {
251 fn drop(this: RootLink<T>) {
252 unsafe {
253 Node::drop((*this.as_ptr()).root);
254 drop(Box::from_raw(this.as_ptr()));
255 }
256 }
257}
258
259impl<T> Node<T> {
260 pub fn new(elt: T) -> Link<T> {
261 let node = Self {
262 val: elt,
263 parent: None,
264 neighbor: (NonNull::dangling(), NonNull::dangling()),
265 any_child: None,
266 order: 0,
267 cut: false,
268 root: None,
269 };
270 let ptr = NonNull::from(Box::leak(Box::new(node)));
271 Node::init_siblings(ptr);
272 ptr
273 }
274
275 pub fn push_child(this: Link<T>, child: Link<T>) {
276 debug_assert!(Node::is_root(this));
277 let par = this.as_ptr();
278 unsafe {
279 (*par).order += 1;
280 if let Some(old_child) = (*par).any_child {
281 Node::push_sibling(old_child, child);
282 } else {
283 Node::init_siblings(child);
284 (*par).any_child = Some(child);
285 }
286 (*child.as_ptr()).parent = Some(this);
287 (*child.as_ptr()).root.take();
288 }
289 }
290
291 pub fn pop_child(this: Link<T>) -> Option<Link<T>> {
292 let par = this.as_ptr();
293 unsafe {
294 let child = (*par).any_child.take()?;
295 (*par).order -= 1;
296 if (*par).parent.is_some() {
297 (*par).cut = true;
299 }
300 (*child.as_ptr()).parent.take();
301 let (prev, next) = (*child.as_ptr()).neighbor;
302 if child == prev {
303 } else {
305 (*par).any_child = Some(next);
307 (*prev.as_ptr()).neighbor.1 = next;
308 (*next.as_ptr()).neighbor.0 = prev;
309 }
310 Node::init_siblings(child);
311 Some(child)
312 }
313 }
314
315 pub fn init_siblings(this: Link<T>) {
316 unsafe { (*this.as_ptr()).neighbor = (this, this) };
317 }
318 pub fn push_sibling(old: Link<T>, new: Link<T>) {
319 unsafe {
320 let neighbor = (*old.as_ptr()).neighbor;
321 if old == neighbor.0 {
322 (*new.as_ptr()).neighbor = (old, old);
324 (*old.as_ptr()).neighbor = (new, new);
325 } else {
326 let next = neighbor.1;
327 (*old.as_ptr()).neighbor.1 = new;
328 (*next.as_ptr()).neighbor.0 = new;
329 (*new.as_ptr()).neighbor = (old, next);
330 }
331 }
332 }
333
334 fn is_root(this: Link<T>) -> bool {
335 unsafe {
336 debug_assert_eq!(
337 (*this.as_ptr()).root.is_some(),
338 (*this.as_ptr()).parent.is_none(),
339 );
340 (*this.as_ptr()).parent.is_none()
341 }
342 }
343
344 pub fn orphan(this: Link<T>) -> Option<Link<T>> {
345 let ptr = this.as_ptr();
346 unsafe {
347 (*ptr).cut = false;
348 let par = (*ptr).parent.take()?;
349
350 let (prev, next) = (*ptr).neighbor;
351 if this == prev {
352 (*par.as_ptr()).any_child.take();
354 } else {
355 (*prev.as_ptr()).neighbor.1 = next;
356 (*next.as_ptr()).neighbor.0 = prev;
357 if this == (*par.as_ptr()).any_child.unwrap() {
358 (*par.as_ptr()).any_child = Some(next);
360 }
361 }
362
363 (*par.as_ptr()).order -= 1;
364 if Node::is_root(par) {
365 None
366 } else if (*par.as_ptr()).cut {
367 Some(par)
369 } else {
370 (*par.as_ptr()).cut = true;
371 None
372 }
373 }
374 }
375
376 fn is_heapified(child: Link<T>) -> bool
377 where
378 T: Ord,
379 {
380 unsafe {
381 match (*child.as_ptr()).parent {
382 Some(par) => (*par.as_ptr()).val >= (*child.as_ptr()).val,
383 _ => true,
384 }
385 }
386 }
387}
388
389impl<T> Node<T> {
390 fn drop(node: Link<T>) {
391 while let Some(child) = Node::pop_child(node) {
392 Self::drop(child);
393 }
394 unsafe { drop(Box::from_raw(node.as_ptr())) };
395 }
396}
397
398impl<T> NodeRef<T> {
399 fn new(node: Link<T>) -> Self { Self { node } }
400}
401
402impl<T> Copy for NodeRef<T> {}
403impl<T> Clone for NodeRef<T> {
404 fn clone(&self) -> Self { *self }
405}
406
407impl<T: Ord> Bucket<T> {
408 pub fn new() -> Self { Self { bucket: vec![] } }
409 pub fn push(&mut self, root: RootLink<T>) {
410 let order = RootNode::order(root);
411 if order >= self.bucket.len() {
412 self.bucket.resize(order + 1, None)
413 }
414 if let Some(old) = self.bucket[order].take() {
415 self.push(RootNode::fuse(root, old));
416 } else {
417 self.bucket[order] = Some(root);
418 }
419 }
420 pub fn take(self) -> impl Iterator<Item = RootLink<T>> {
421 self.bucket.into_iter().filter_map(std::convert::identity)
422 }
423}
424
425#[test]
426fn nonnull_eq() {
427 use std::ptr::NonNull;
428
429 #[allow(unused)]
430 struct A(i32);
431
432 let a1 = NonNull::from(Box::leak(Box::new(A(0))));
433 let a2 = a1;
434 let b = NonNull::from(Box::leak(Box::new(A(0))));
435 assert_ne!(a1, b);
436 assert_eq!(a1, a2);
437
438 unsafe { *a1.as_ptr() = A(1) };
439 assert_eq!(a1, a2);
440
441 unsafe { *a2.as_ptr() = A(2) };
442 assert_eq!(a1, a2);
443
444 unsafe {
445 drop(Box::from_raw(a1.as_ptr()));
446 drop(Box::from_raw(b.as_ptr()));
447 }
448}
449
450#[test]
451fn memleak() {
452 use std::ptr::NonNull;
453
454 #[allow(unused)]
455 struct A(i32);
456
457 let a = NonNull::from(Box::leak(Box::new(A(0))));
458 let a_box = unsafe { Box::from_raw(a.as_ptr()) };
459 assert_eq!(a_box.0, 0);
460}
461
462#[test]
463fn nested_leak() {
464 use std::ptr::NonNull;
465
466 struct A(i32);
467 #[allow(unused)]
468 struct B(NonNull<A>);
469 let a = NonNull::from(Box::leak(Box::new(A(100))));
470 let b = NonNull::from(Box::leak(Box::new(B(a))));
471 let a0 = unsafe {
472 drop(Box::from_raw(b.as_ptr()));
473 Box::from_raw(a.as_ptr()).0
474 };
475 assert_eq!(a0, 100);
476}
477
478#[test]
479fn mutual_ref() {
480 use std::ptr::NonNull;
481
482 struct A(NonNull<A>);
483 let a = NonNull::from(Box::leak(Box::new(A(NonNull::dangling()))));
484 let b = NonNull::from(Box::leak(Box::new(A(NonNull::dangling()))));
485 unsafe {
486 (*a.as_ptr()).0 = b;
487 (*b.as_ptr()).0 = a;
488 (*a.as_ptr()).0 = b;
489 };
490
491 unsafe {
492 drop(Box::from_raw(a.as_ptr()));
493 drop(Box::from_raw(b.as_ptr()));
494 }
495}
496
497#[cfg(test)]
498mod tests {
499 use super::*;
500
501 #[test]
502 fn single() {
503 let mut q = FibonacciHeap::new();
504 q.push(1);
505 q.push(2);
506 q.push(3);
507 q.pop();
508 }
509
510 #[test]
511 fn push_meld_pop() {
512 let mut q = FibonacciHeap::new();
513 assert!(q.is_empty());
514 q.push(1);
515 q.push(3);
516 q.push(4);
517 assert_eq!(q.len(), 3);
518
519 let mut r = FibonacciHeap::new();
520 r.push(0);
521 r.push(2);
522 q.meld(r);
523 assert_eq!(q.len(), 5);
524
525 let mut actual = vec![];
526 for i in (0..5).rev() {
527 actual.extend(q.pop());
528 assert_eq!(q.len(), i);
529 }
530 assert_eq!(actual, [4, 3, 2, 1, 0]);
531 }
532
533 #[test]
534 fn many_pushes() {
535 let mut q = FibonacciHeap::new();
536 let mut r = FibonacciHeap::new();
537 for i in 0..100 {
538 q.push(i);
539 r.push(i);
540 assert_eq!(q.len(), i + 1);
541 }
542 let mut res = vec![];
543 for i in (0..100).rev() {
544 res.extend(q.pop());
545 assert_eq!(q.len(), i);
546 }
547 }
548
549 #[test]
550 fn heap_sort() {
551 let n = 1 << 8;
552 let mut q = FibonacciHeap::new();
553 for i in (0..n).map(|i| (i >> 1) ^ i) {
554 q.push(i);
555 }
556 let actual = (0..n).map(|_| q.pop().unwrap());
557 assert!(actual.eq((0..n).rev()));
558 }
559
560 #[test]
561 fn urge() {
562 let mut q = FibonacciHeap::new();
563 q.push(1);
564 let x2 = q.push(2);
565 q.push(3);
566 unsafe { q.urge(x2, 20) };
567 let actual: Vec<_> = (0..q.len()).map(|_| q.pop().unwrap()).collect();
568 assert_eq!(actual, [20, 3, 1]);
569
570 let x2 = q.push(2);
571 let x1 = q.push(1);
572 let _x6 = q.push(6);
573 let x3 = q.push(3);
574 let x5 = q.push(5);
575 let _x4 = q.push(4);
576 let _x7 = q.push(7);
577 assert_eq!(q.pop(), Some(7));
578
579 unsafe { q.urge(x5, 500) };
580 assert_eq!(q.pop(), Some(500));
581
582 unsafe { q.urge(x1, 4) };
583 assert_eq!(q.pop(), Some(6));
584
585 unsafe { q.urge(x2, 1) };
586 assert_eq!(q.pop(), Some(4));
587
588 unsafe { q.urge(x3, 5) };
589 assert_eq!(q.pop(), Some(5));
590
591 unsafe { q.urge(x2, 10) };
592 assert_eq!(q.pop(), Some(10));
593
594 assert_eq!(q.pop(), Some(4));
595 assert!(q.is_empty());
596 }
597}
598
599