1
+ package com .williamfiset .algorithms .datastructures .fibonacciheap ;
2
+
3
+ //Disclaimer: implementation based on "http://staff.ustc.edu.cn/~csli/graduate/algorithms/book6/chap21.htm"
4
+ //Credits to the respective owner for code
5
+
1
6
import static java .lang .Math .floor ;
2
7
import static java .lang .Math .log ;
3
8
import static java .lang .Math .sqrt ;
13
18
import java .util .Set ;
14
19
import java .util .Stack ;
15
20
16
- /**
17
- * A Fibonacci Heap implementation based on
18
- * <a href="http://staff.ustc.edu.cn/~csli/graduate/algorithms/book6/chap21.htm">University of Science and Technology of
19
- * China</a> lesson.
20
- *
21
- * <p><b>Note 1</b>: this class is NOT thread safe!</p>
22
- *
23
- * <p><b>Note 2</b>: this class doesn't support {@code null} values</p>
24
- *
25
- * @param <E> the type of elements held in this collection.
26
- */
21
+
27
22
public final class FibonacciHeap <E >
28
23
implements Queue <E >
29
24
{
30
25
31
- /**
32
- * The <i>Phi</i> constant value.
33
- */
26
+
34
27
private static final double LOG_PHI = log ( ( 1 + sqrt ( 5 ) ) / 2 );
35
28
36
- /**
37
- * A simple index of stored elements.
38
- */
39
29
private final Set <E > elementsIndex = new HashSet <E >();
40
30
41
- /**
42
- * The comparator, or null if priority queue uses elements'
43
- * natural ordering.
44
- */
45
31
private final Comparator <? super E > comparator ;
46
32
47
- /**
48
- * The number of nodes currently in {@code H} is kept in {@code n[H]}.
49
- */
50
33
private int size = 0 ;
51
34
52
- /**
53
- * {@code t(H)} the number of trees in the root list.
54
- */
55
35
private int trees = 0 ;
56
36
57
- /**
58
- * {@code m(H)} the number of marked nodes in {@code H}.
59
- */
60
37
private int markedNodes = 0 ;
61
38
62
- /**
63
- * The root of the tree containing a minimum key {@code min[H]}.
64
- */
65
39
private FibonacciHeapNode <E > minimumNode ;
66
40
67
- /**
68
- * Creates a {@link FibonacciHeap} that orders its elements according to their natural ordering.
69
- */
70
41
public FibonacciHeap ()
71
42
{
72
43
this ( null );
73
44
}
74
45
75
- /**
76
- * Creates a {@link FibonacciHeap} that orders its elements according to the specified comparator.
77
- *
78
- * @param comparator the comparator that will be used to order this queue.
79
- * If null, the natural ordering of the elements will be used.
80
- */
46
+
81
47
public FibonacciHeap ( /* @Nullable */ Comparator <? super E > comparator )
82
48
{
83
49
this .comparator = comparator ;
84
50
}
85
51
86
- /**
87
- * Moves the target node in the {@code H} root nodes.
88
- *
89
- * @param node the node has to be moved in the {@code H} root nodes
90
- * @see #add(Object)
91
- * @see #consolidate()
92
- * @see #cut(FibonacciHeapNode, FibonacciHeapNode)
93
- */
94
52
private void moveToRoot ( FibonacciHeapNode <E > node )
95
53
{
96
54
// 8' if min[H] = NIL
@@ -119,21 +77,6 @@ private void moveToRoot( FibonacciHeapNode<E> node )
119
77
}
120
78
}
121
79
122
- /**
123
- * {@inheritDoc}
124
- *
125
- * <pre>FIB-HEAP-INSERT(H, x)
126
- * 1 degree[x] ← 0
127
- * 2 p[x] ← NIL
128
- * 3 child[x] ← NIL
129
- * 4 left[x] ← x
130
- * 5 right[x] ← x
131
- * 6 mark[x] ← FALSE
132
- * 7 concatenate the root list containing x with root list H
133
- * 8 if min[H] = NIL or key[x] < key[min[H]]
134
- * 9 then min[H] ← x
135
- * 10 n[H] ← n[H] + 1</pre>
136
- */
137
80
public boolean add ( E e )
138
81
{
139
82
if ( e == null )
@@ -311,23 +254,6 @@ public E peek()
311
254
return minimumNode .getElement ();
312
255
}
313
256
314
- /**
315
- * {@inheritDoc}
316
- *
317
- * <pre>FIB-HEAP-EXTRACT-MIN(H)
318
- * 1 z ← min[H]
319
- * 2 if z ≠ NIL
320
- * 3 then for each child x of z
321
- * 4 do add x to the root list of H
322
- * 5 p[x] ← NIL
323
- * 6 remove z from the root list of H
324
- * 7 if z = right[z]
325
- * 8 then min[H] ← NIL
326
- * 9 else min[H] ← right[z]
327
- * 10 CONSOLIDATE(H)
328
- * 11 n[H] ← n[H] - 1
329
- * 12 return z</pre>
330
- */
331
257
public E poll ()
332
258
{
333
259
// 2 if z ≠ NIL
@@ -400,30 +326,6 @@ public E remove()
400
326
return poll ();
401
327
}
402
328
403
- /**
404
- * Implements the {@code CONSOLIDATE(H)} function.
405
- *
406
- * <pre>CONSOLIDATE(H)
407
- * 1 for i ← 0 to D(n[H])
408
- * 2 do A[i] ← NIL
409
- * 3 for each node w in the root list of H
410
- * 4 do x ← w
411
- * 5 d ← degree[x]
412
- * 6 while A[d] ≠ NIL
413
- * 7 do y ← A[d]
414
- * 8 if key[x] > key[y]
415
- * 9 then exchange x ↔ y
416
- * 10 FIB-HEAP-LINK(H,y,x)
417
- * 11 A[d] ← NIL
418
- * 12 d ← d + 1
419
- * 13 A[d] ← x
420
- * 14 min[H] ← NIL
421
- * 15 for i ← 0 to D(n[H])
422
- * 16 do if A[i] ≠ NIL
423
- * 17 then add A[i] to the root list of H
424
- * 18 if min[H] = NIL or key[A[i]] ≤ key[min[H]]
425
- * 19 then min[H] ← A[i]</pre>
426
- */
427
329
private void consolidate ()
428
330
{
429
331
if ( isEmpty () )
@@ -525,17 +427,6 @@ private void consolidate()
525
427
}
526
428
}
527
429
528
- /**
529
- * Implements the {@code FIB-HEAP-LINK(H, y, x)} function.
530
- *
531
- * <pre>FIB-HEAP-LINK(H, y, x)
532
- * 1 remove y from the root list of H
533
- * 2 make y a child of x, incrementing degree[x]
534
- * 3 mark[y] FALSE</pre>
535
- *
536
- * @param y the node has to be removed from the root list
537
- * @param x the node has to to become fater of {@code y}
538
- */
539
430
private void link ( FibonacciHeapNode <E > y , FibonacciHeapNode <E > x )
540
431
{
541
432
// 1 remove y from the root list of H
@@ -566,18 +457,6 @@ private void link( FibonacciHeapNode<E> y, FibonacciHeapNode<E> x )
566
457
markedNodes ++;
567
458
}
568
459
569
- /**
570
- * Implements the {@code CUT(H,x,y)} function.
571
- *
572
- * <pre>CUT(H,x,y)
573
- * 1 remove x from the child list of y, decrementing degree[y]
574
- * 2 add x to the root list of H
575
- * 3 p[x] ← NIL
576
- * 4 mark[x] ← FALSE</pre>
577
- *
578
- * @param x the node has to be removed from {@code y} children
579
- * @param y the node has to be updated
580
- */
581
460
private void cut ( FibonacciHeapNode <E > x , FibonacciHeapNode <E > y )
582
461
{
583
462
// add x to the root list of H
@@ -593,19 +472,6 @@ private void cut( FibonacciHeapNode<E> x, FibonacciHeapNode<E> y )
593
472
markedNodes --;
594
473
}
595
474
596
- /**
597
- * Implements the {@code CASCADING-CUT(H,y)} function.
598
- *
599
- * <pre>CASCADING-CUT(H,y)
600
- * 1 z ← p[y]
601
- * 2 if z ≠ NIL
602
- * 3 then if mark[y] = FALSE
603
- * 4 then mark[y] ← TRUE
604
- * 5 else CUT(H,y,z)
605
- * 6 CASCADING-CUT(H,z)</pre>
606
- *
607
- * @param y the target node to apply CASCADING-CUT
608
- */
609
475
private void cascadingCut ( FibonacciHeapNode <E > y )
610
476
{
611
477
// z <- p[y]
@@ -631,26 +497,12 @@ private void cascadingCut( FibonacciHeapNode<E> y )
631
497
}
632
498
}
633
499
634
- /**
635
- * The potential of Fibonacci heap {@code H} is then defined by
636
- * {@code t(H) + 2m(H)}.
637
- *
638
- * @return The potential of this Fibonacci heap.
639
- */
640
500
public int potential ()
641
501
{
642
502
return trees + 2 * markedNodes ;
643
503
}
644
504
645
- /**
646
- * Compare the given objects according to to the specified comparator if not null,
647
- * according to their natural ordering otherwise.
648
- *
649
- * @param o1 the first {@link FibonacciHeap} node to be compared
650
- * @param o2 the second {@link FibonacciHeap} node to be compared
651
- * @return a negative integer, zero, or a positive integer as the first argument is
652
- * less than, equal to, or greater than the second
653
- */
505
+
654
506
private int compare ( FibonacciHeapNode <E > o1 , FibonacciHeapNode <E > o2 )
655
507
{
656
508
if ( comparator != null )
0 commit comments