Skip to content

refactor: Enhance docs, add tests in FibonacciHeap #5979

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
package com.thealgorithms.datastructures.heaps;

/**
* The {@code FibonacciHeap} class implements a Fibonacci Heap data structure,
* which is a collection of trees that satisfy the minimum heap property.
* This heap allows for efficient merging of heaps, as well as faster
* decrease-key and delete operations compared to other heap data structures.
*
* <p>Key features of the Fibonacci Heap include:
* <ul>
* <li>Amortized O(1) time complexity for insert and decrease-key operations.</li>
* <li>Amortized O(log n) time complexity for delete and delete-min operations.</li>
* <li>Meld operation that combines two heaps in O(1) time.</li>
* <li>Potential function that helps analyze the amortized time complexity.</li>
* </ul>
*
* <p>This implementation maintains additional statistics such as the total number
* of link and cut operations performed during the lifetime of the heap, which can
* be accessed through static methods.
*
* <p>The Fibonacci Heap is composed of nodes represented by the inner class
* {@code HeapNode}. Each node maintains a key, rank, marked status, and pointers
* to its children and siblings. Nodes can be linked and cut as part of the heap
* restructuring processes.
*
* @see HeapNode
*/
public class FibonacciHeap {

private static final double GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,103 @@
public class FibonacciHeapTest {

@Test
void testHeap() {
void testHeapInsertionAndMinimum() {
FibonacciHeap fibonacciHeap = new FibonacciHeap();
fibonacciHeap.insert(5);
fibonacciHeap.insert(3);
fibonacciHeap.insert(1);
fibonacciHeap.insert(18);
fibonacciHeap.insert(33);

Assertions.assertEquals(fibonacciHeap.findMin().getKey(), 1);
Assertions.assertEquals(1, fibonacciHeap.findMin().getKey());
fibonacciHeap.deleteMin();
Assertions.assertEquals(fibonacciHeap.findMin().getKey(), 3);
Assertions.assertEquals(3, fibonacciHeap.findMin().getKey());
}

@Test
void testDeleteMinOnSingleElementHeap() {
FibonacciHeap fibonacciHeap = new FibonacciHeap(10);
Assertions.assertEquals(10, fibonacciHeap.findMin().getKey());
fibonacciHeap.deleteMin();
Assertions.assertTrue(fibonacciHeap.empty());
}

@Test
void testHeapMeld() {
FibonacciHeap heap1 = new FibonacciHeap();
FibonacciHeap heap2 = new FibonacciHeap();
heap1.insert(1);
heap1.insert(2);
heap2.insert(3);
heap2.insert(4);

heap1.meld(heap2);
Assertions.assertEquals(1, heap1.findMin().getKey());
}

@Test
void testHeapSize() {
FibonacciHeap fibonacciHeap = new FibonacciHeap();
Assertions.assertEquals(0, fibonacciHeap.size());
fibonacciHeap.insert(5);
Assertions.assertEquals(1, fibonacciHeap.size());
fibonacciHeap.insert(3);
Assertions.assertEquals(2, fibonacciHeap.size());
fibonacciHeap.deleteMin();
Assertions.assertEquals(1, fibonacciHeap.size());
}

@Test
void testCountersRep() {
FibonacciHeap fibonacciHeap = new FibonacciHeap();
fibonacciHeap.insert(5);
fibonacciHeap.insert(3);
fibonacciHeap.insert(8);
fibonacciHeap.insert(1);

int[] counters = fibonacciHeap.countersRep();
Assertions.assertEquals(4, counters[0]);
Assertions.assertEquals(0, counters[1]);
}

@Test
void testDeleteMinMultipleElements() {
FibonacciHeap fibonacciHeap = new FibonacciHeap();
fibonacciHeap.insert(5);
fibonacciHeap.insert(2);
fibonacciHeap.insert(8);
fibonacciHeap.insert(1);

Assertions.assertEquals(1, fibonacciHeap.findMin().getKey());
fibonacciHeap.deleteMin();
Assertions.assertEquals(2, fibonacciHeap.findMin().getKey());
}

@Test
void testInsertNegativeKeys() {
FibonacciHeap fibonacciHeap = new FibonacciHeap();
fibonacciHeap.insert(-10);
fibonacciHeap.insert(-5);
fibonacciHeap.insert(-20);

Assertions.assertEquals(-20, fibonacciHeap.findMin().getKey());
}

@Test
void testDeleteOnEmptyHeap() {
FibonacciHeap fibonacciHeap = new FibonacciHeap();
Assertions.assertThrows(NullPointerException.class, () -> { fibonacciHeap.delete(fibonacciHeap.findMin()); });
}

@Test
void testPotentialCalculation() {
FibonacciHeap fibonacciHeap = new FibonacciHeap();
fibonacciHeap.insert(10);
fibonacciHeap.insert(20);

Assertions.assertEquals(2, fibonacciHeap.potential()); // 2 trees, no marked nodes
var node = fibonacciHeap.findMin();
fibonacciHeap.delete(node);
Assertions.assertEquals(1, fibonacciHeap.potential());
}
}