From 8ffab6620ebd8b62c0e48c6bdd3046b0d814f272 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Thu, 24 Oct 2024 12:35:07 +0530 Subject: [PATCH 1/6] refactor: Enhance docs, add tests in `MinHeap` --- .../datastructures/heaps/Heap.java | 2 +- .../datastructures/heaps/HeapElement.java | 6 +- .../datastructures/heaps/MinHeap.java | 244 ++++++++++++++---- .../datastructures/heaps/MinHeapTest.java | 141 ++++++++++ 4 files changed, 341 insertions(+), 52 deletions(-) create mode 100644 src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java b/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java index 63e101d9b13d..8cb93edf78f3 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java @@ -40,5 +40,5 @@ public interface Heap { * @param elementIndex int containing the position in the heap of the * element to be deleted. */ - void deleteElement(int elementIndex); + void deleteElement(int elementIndex) throws EmptyHeapException; } diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java b/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java index 7c457a340645..e9a29dad016a 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java @@ -111,7 +111,7 @@ public String toString() { } /** - * @param otherHeapElement + * @param o * @return true if the keys on both elements are identical and the * additional info objects are identical. */ @@ -134,4 +134,8 @@ public int hashCode() { result = 31 * result + (additionalInfo != null ? additionalInfo.hashCode() : 0); return result; } + + public String getValue() { + return additionalInfo.toString(); + } } diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java index 46864fba0047..243e3e87e6e0 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java @@ -4,8 +4,25 @@ import java.util.List; /** - * Heap tree where a node's key is higher than or equal to its parent's and - * lower than or equal to its children's. + * A Min Heap implementation where each node's key is lower than or equal to its children's keys. + * This data structure provides O(log n) time complexity for insertion and deletion operations, + * and O(1) for retrieving the minimum element. + * + * Properties: + * 1. Complete Binary Tree + * 2. Parent node's key ≤ Children nodes' keys + * 3. Root contains the minimum element + * + * Example usage: + * ```java + * List elements = Arrays.asList( + * new HeapElement(5, "Five"), + * new HeapElement(2, "Two") + * ); + * MinHeap heap = new MinHeap(elements); + * heap.insertElement(new HeapElement(1, "One")); + * HeapElement min = heap.getElement(); // Returns and removes the minimum element + * ``` * * @author Nicolas Renard */ @@ -13,113 +30,240 @@ public class MinHeap implements Heap { private final List minHeap; + /** + * Constructs a new MinHeap from a list of elements. + * Null elements in the input list are ignored with a warning message. + * + * @param listElements List of HeapElement objects to initialize the heap + * @throws IllegalArgumentException if the input list is null + */ public MinHeap(List listElements) { + if (listElements == null) { + throw new IllegalArgumentException("Input list cannot be null"); + } + minHeap = new ArrayList<>(); + + // Safe initialization: directly add elements first for (HeapElement heapElement : listElements) { if (heapElement != null) { - insertElement(heapElement); + minHeap.add(heapElement); } else { System.out.println("Null element. Not added to heap"); } } + + // Heapify the array bottom-up + for (int i = minHeap.size() / 2; i >= 0; i--) { + heapifyDown(i + 1); + } + if (minHeap.isEmpty()) { System.out.println("No element has been added, empty heap."); } } - // Get the element at a given index. The key for the list is equal to index value - 1 + /** + * Retrieves the element at the specified index without removing it. + * Note: The index is 1-based for consistency with heap operations. + * + * @param elementIndex 1-based index of the element to retrieve + * @return HeapElement at the specified index + * @throws IndexOutOfBoundsException if the index is invalid + */ public HeapElement getElement(int elementIndex) { if ((elementIndex <= 0) || (elementIndex > minHeap.size())) { - throw new IndexOutOfBoundsException("Index out of heap range"); + throw new IndexOutOfBoundsException("Index " + elementIndex + " is out of heap range [1, " + minHeap.size() + "]"); } return minHeap.get(elementIndex - 1); } - // Get the key of the element at a given index + /** + * Retrieves the key value of an element at the specified index. + * + * @param elementIndex 1-based index of the element + * @return double value representing the key + * @throws IndexOutOfBoundsException if the index is invalid + */ private double getElementKey(int elementIndex) { if ((elementIndex <= 0) || (elementIndex > minHeap.size())) { - throw new IndexOutOfBoundsException("Index out of heap range"); + throw new IndexOutOfBoundsException("Index " + elementIndex + " is out of heap range [1, " + minHeap.size() + "]"); } - return minHeap.get(elementIndex - 1).getKey(); } - // Swaps two elements in the heap + /** + * Swaps two elements in the heap. + * + * @param index1 1-based index of first element + * @param index2 1-based index of second element + */ private void swap(int index1, int index2) { HeapElement temporaryElement = minHeap.get(index1 - 1); minHeap.set(index1 - 1, minHeap.get(index2 - 1)); minHeap.set(index2 - 1, temporaryElement); } - // Toggle an element up to its right place as long as its key is lower than its parent's + /** + * Maintains heap properties by moving an element down the heap. + * Used specifically during initialization. + * + * @param elementIndex 1-based index of the element to heapify + */ + private void heapifyDown(int elementIndex) { + int smallest = elementIndex - 1; // Convert to 0-based index + int leftChild = 2 * elementIndex - 1; + int rightChild = 2 * elementIndex; + + // Check if left child is smaller than root + if (leftChild < minHeap.size() && minHeap.get(leftChild).getKey() < minHeap.get(smallest).getKey()) { + smallest = leftChild; + } + + // Check if right child is smaller than smallest so far + if (rightChild < minHeap.size() && minHeap.get(rightChild).getKey() < minHeap.get(smallest).getKey()) { + smallest = rightChild; + } + + // If smallest is not root + if (smallest != elementIndex - 1) { + HeapElement swap = minHeap.get(elementIndex - 1); + minHeap.set(elementIndex - 1, minHeap.get(smallest)); + minHeap.set(smallest, swap); + + // Recursively heapify the affected sub-tree + heapifyDown(smallest + 1); // Convert back to 1-based index + } + } + + /** + * Moves an element up the heap until heap properties are satisfied. + * This operation is called after insertion to maintain heap properties. + * + * @param elementIndex 1-based index of the element to move up + */ private void toggleUp(int elementIndex) { + if (elementIndex <= 1) return; + double key = minHeap.get(elementIndex - 1).getKey(); - while (getElementKey((int) Math.floor(elementIndex / 2.0) + 1) > key) { - swap(elementIndex, (int) Math.floor(elementIndex / 2.0)); - elementIndex = (int) Math.floor(elementIndex / 2.0); + int parentIndex = (int) Math.floor(elementIndex / 2.0); + + while (elementIndex > 1 && getElementKey(parentIndex) > key) { + swap(elementIndex, parentIndex); + elementIndex = parentIndex; + parentIndex = (int) Math.floor(elementIndex / 2.0); } } - // Toggle an element down to its right place as long as its key is higher - // than any of its children's + /** + * Moves an element down the heap until heap properties are satisfied. + * This operation is called after deletion to maintain heap properties. + * + * @param elementIndex 1-based index of the element to move down + */ private void toggleDown(int elementIndex) { double key = minHeap.get(elementIndex - 1).getKey(); - boolean wrongOrder = (key > getElementKey(elementIndex * 2)) || (key > getElementKey(Math.min(elementIndex * 2, minHeap.size()))); - while ((2 * elementIndex <= minHeap.size()) && wrongOrder) { - // Check whether it shall swap the element with its left child or its right one if any. - if ((2 * elementIndex < minHeap.size()) && (getElementKey(elementIndex * 2 + 1) < getElementKey(elementIndex * 2))) { - swap(elementIndex, 2 * elementIndex + 1); - elementIndex = 2 * elementIndex + 1; - } else { - swap(elementIndex, 2 * elementIndex); - elementIndex = 2 * elementIndex; + int size = minHeap.size(); + + while (true) { + int smallest = elementIndex; + int leftChild = 2 * elementIndex; + int rightChild = 2 * elementIndex + 1; + + if (leftChild <= size && getElementKey(leftChild) < key) { + smallest = leftChild; + } + + if (rightChild <= size && getElementKey(rightChild) < getElementKey(smallest)) { + smallest = rightChild; + } + + if (smallest == elementIndex) { + break; } - wrongOrder = (key > getElementKey(elementIndex * 2)) || (key > getElementKey(Math.min(elementIndex * 2, minHeap.size()))); + + swap(elementIndex, smallest); + elementIndex = smallest; } } - private HeapElement extractMin() { + /** + * Extracts and returns the minimum element from the heap. + * + * @return HeapElement with the lowest key + * @throws EmptyHeapException if the heap is empty + */ + private HeapElement extractMin() throws EmptyHeapException { + if (minHeap.isEmpty()) { + throw new EmptyHeapException("Cannot extract from empty heap"); + } HeapElement result = minHeap.get(0); - deleteElement(0); + deleteElement(1); return result; } + /** + * {@inheritDoc} + */ @Override - public final void insertElement(HeapElement element) { + public void insertElement(HeapElement element) { + if (element == null) { + throw new IllegalArgumentException("Cannot insert null element"); + } minHeap.add(element); toggleUp(minHeap.size()); } + /** + * {@inheritDoc} + */ @Override - public void deleteElement(int elementIndex) { + public void deleteElement(int elementIndex) throws EmptyHeapException { if (minHeap.isEmpty()) { - try { - throw new EmptyHeapException("Attempt to delete an element from an empty heap"); - } catch (EmptyHeapException e) { - e.printStackTrace(); - } + throw new EmptyHeapException("Cannot delete from empty heap"); } if ((elementIndex > minHeap.size()) || (elementIndex <= 0)) { - throw new IndexOutOfBoundsException("Index out of heap range"); - } - // The last element in heap replaces the one to be deleted - minHeap.set(elementIndex - 1, getElement(minHeap.size())); - minHeap.remove(minHeap.size()); - // Shall the new element be moved up... - if (getElementKey(elementIndex) < getElementKey((int) Math.floor(elementIndex / 2.0))) { - toggleUp(elementIndex); - } // ... or down ? - else if (((2 * elementIndex <= minHeap.size()) && (getElementKey(elementIndex) > getElementKey(elementIndex * 2))) || ((2 * elementIndex < minHeap.size()) && (getElementKey(elementIndex) > getElementKey(elementIndex * 2)))) { - toggleDown(elementIndex); + throw new IndexOutOfBoundsException("Index " + elementIndex + " is out of heap range [1, " + minHeap.size() + "]"); + } + + // Replace with last element and remove last position + minHeap.set(elementIndex - 1, minHeap.get(minHeap.size() - 1)); + minHeap.remove(minHeap.size() - 1); + + // No need to toggle if we just removed the last element + if (!minHeap.isEmpty() && elementIndex <= minHeap.size()) { + // Determine whether to toggle up or down + if (elementIndex > 1 && getElementKey(elementIndex) < getElementKey((int) Math.floor(elementIndex / 2.0))) { + toggleUp(elementIndex); + } else { + toggleDown(elementIndex); + } } } + /** + * {@inheritDoc} + */ @Override public HeapElement getElement() throws EmptyHeapException { - try { - return extractMin(); - } catch (Exception e) { - throw new EmptyHeapException("Heap is empty. Error retrieving element", e); - } + return extractMin(); + } + + /** + * Returns the current size of the heap. + * + * @return number of elements in the heap + */ + public int size() { + return minHeap.size(); + } + + /** + * Checks if the heap is empty. + * + * @return true if the heap contains no elements + */ + public boolean isEmpty() { + return minHeap.isEmpty(); } } diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java new file mode 100644 index 000000000000..1c2caf54cdb1 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java @@ -0,0 +1,141 @@ +package com.thealgorithms.datastructures.heaps; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class MinHeapTest { + + private MinHeap heap; + + @BeforeEach + void setUp() { + // Create a fresh heap for each test + List elements = Arrays.asList(new HeapElement(5.0, "Five"), new HeapElement(2.0, "Two"), new HeapElement(8.0, "Eight"), new HeapElement(1.0, "One"), new HeapElement(9.0, "Nine")); + heap = new MinHeap(elements); + } + + @Test + void testConstructorWithNullList() { + assertThrows(IllegalArgumentException.class, () -> new MinHeap(null)); + } + + @Test + void testConstructorWithEmptyList() { + MinHeap emptyHeap = new MinHeap(new ArrayList<>()); + assertTrue(emptyHeap.isEmpty()); + } + + @Test + void testConstructorWithNullElements() { + List elements = Arrays.asList(new HeapElement(1.0, "One"), null, new HeapElement(2.0, "Two")); + MinHeap heap = new MinHeap(elements); + assertEquals(2, heap.size()); + } + + @Test + void testInsertElement() { + heap.insertElement(new HeapElement(0.5, "Half")); + assertEquals(0.5, heap.getElement(1).getKey()); + assertEquals(6, heap.size()); + } + + @Test + void testInsertNullElement() { + assertThrows(IllegalArgumentException.class, () -> heap.insertElement(null)); + } + + @Test + void testGetElementAtIndex() { + HeapElement element = heap.getElement(1); + assertEquals(1.0, element.getKey()); + assertEquals("One", element.getValue()); + } + + @Test + void testGetElementAtInvalidIndex() { + assertThrows(IndexOutOfBoundsException.class, () -> heap.getElement(0)); + assertThrows(IndexOutOfBoundsException.class, () -> heap.getElement(10)); + } + + @Test + void testDeleteElement() throws EmptyHeapException { + heap.deleteElement(1); + assertEquals(2.0, heap.getElement(1).getKey()); + assertEquals(4, heap.size()); + } + + @Test + void testDeleteElementAtInvalidIndex() { + assertThrows(IndexOutOfBoundsException.class, () -> heap.deleteElement(0)); + assertThrows(IndexOutOfBoundsException.class, () -> heap.deleteElement(10)); + } + + @Test + void testDeleteFromEmptyHeap() { + MinHeap emptyHeap = new MinHeap(new ArrayList<>()); + assertThrows(EmptyHeapException.class, () -> emptyHeap.deleteElement(1)); + } + + @Test + void testExtractMin() throws EmptyHeapException { + HeapElement min = heap.getElement(); + assertEquals(1.0, min.getKey()); + assertEquals("One", min.getValue()); + assertEquals(4, heap.size()); + + min = heap.getElement(); + assertEquals(2.0, min.getKey()); + assertEquals(3, heap.size()); + } + + @Test + void testExtractMinFromEmptyHeap() { + MinHeap emptyHeap = new MinHeap(new ArrayList<>()); + assertThrows(EmptyHeapException.class, () -> emptyHeap.getElement()); + } + + @Test + void testHeapOrder() { + // Test that parent is always smaller than or equal to children + for (int i = 1; i <= heap.size() / 2; i++) { + double parentKey = heap.getElement(i).getKey(); + + // Check left child + if (2 * i <= heap.size()) { + assertTrue(parentKey <= heap.getElement(2 * i).getKey()); + } + + // Check right child + if (2 * i + 1 <= heap.size()) { + assertTrue(parentKey <= heap.getElement(2 * i + 1).getKey()); + } + } + } + + @Test + void testSizeAndEmpty() { + assertEquals(5, heap.size()); + assertFalse(heap.isEmpty()); + + // Remove all elements + while (!heap.isEmpty()) { + try { + heap.getElement(); + } catch (EmptyHeapException e) { + Assertions.fail("Should not throw EmptyHeapException while heap is not empty"); + } + } + + assertEquals(0, heap.size()); + assertTrue(heap.isEmpty()); + } +} From 9b273cb3d665e43b632e079e069c7df09d274634 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Thu, 24 Oct 2024 07:05:25 +0000 Subject: [PATCH 2/6] Update directory --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 1def3e25c064..61521a8715e9 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -827,6 +827,7 @@ * heaps * [FibonacciHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java) * [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java) + * [MinHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java) * lists * [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java) * [CreateAndDetectLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java) From cc0a6d9f7d8d428b3aa74bfa210801970349e664 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Thu, 24 Oct 2024 12:35:33 +0530 Subject: [PATCH 3/6] Fix --- .../com/thealgorithms/datastructures/heaps/MinHeap.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java index 243e3e87e6e0..c281d6a38d41 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java @@ -197,7 +197,7 @@ private HeapElement extractMin() throws EmptyHeapException { if (minHeap.isEmpty()) { throw new EmptyHeapException("Cannot extract from empty heap"); } - HeapElement result = minHeap.get(0); + HeapElement result = minHeap.getFirst(); deleteElement(1); return result; } @@ -227,8 +227,8 @@ public void deleteElement(int elementIndex) throws EmptyHeapException { } // Replace with last element and remove last position - minHeap.set(elementIndex - 1, minHeap.get(minHeap.size() - 1)); - minHeap.remove(minHeap.size() - 1); + minHeap.set(elementIndex - 1, minHeap.getLast()); + minHeap.removeLast(); // No need to toggle if we just removed the last element if (!minHeap.isEmpty() && elementIndex <= minHeap.size()) { From 78794e6046d6e251722c1efc697d0c8e70ad53a0 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Thu, 24 Oct 2024 12:39:40 +0530 Subject: [PATCH 4/6] Fix --- .../java/com/thealgorithms/datastructures/heaps/MinHeap.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java index c281d6a38d41..3a4822142b5f 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java @@ -143,7 +143,9 @@ private void heapifyDown(int elementIndex) { * @param elementIndex 1-based index of the element to move up */ private void toggleUp(int elementIndex) { - if (elementIndex <= 1) return; + if (elementIndex <= 1) { + return; + } double key = minHeap.get(elementIndex - 1).getKey(); int parentIndex = (int) Math.floor(elementIndex / 2.0); From 337d53b4b96826633125080c88a78ab6e09b4e4d Mon Sep 17 00:00:00 2001 From: Hardvan Date: Sat, 26 Oct 2024 06:22:14 +0000 Subject: [PATCH 5/6] Update directory --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 31ff69794bca..c389bce7c8d4 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -836,6 +836,7 @@ * [GenericHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java) * [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java) * [MinHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java) + * [MinPriorityQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java) * lists * [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java) * [CountSinglyLinkedListRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursionTest.java) From aefee11507dfe8e538ebdfad9f79203975d08b63 Mon Sep 17 00:00:00 2001 From: siriak Date: Sat, 26 Oct 2024 16:41:38 +0000 Subject: [PATCH 6/6] Update directory --- DIRECTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index ae86f079dc56..f8bb3711a664 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -869,9 +869,9 @@ * [HeapElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/HeapElementTest.java) * [KthElementFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java) * [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java) - * [MinHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java) * [MedianFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java) * [MergeKSortedArraysTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java) + * [MinHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java) * [MinPriorityQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java) * lists * [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy