Add Leftist Heap (#3789)

Co-authored-by: Adrian Paras <aparas@terpmail.umd.edu>
This commit is contained in:
adrianparas 2022-12-29 07:19:35 -05:00 committed by GitHub
parent 6a0035d872
commit 9123474729
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 146 additions and 0 deletions

View File

@ -0,0 +1,118 @@
package com.thealgorithms.datastructures.heaps;
import java.util.ArrayList;
/*
* This is a leftist heap that follows the same operations as a
* binary min heap, but may be unbalanced at times and follows a
* leftist property, in which the left side is more heavy on the
* right based on the null-path length (npl) values.
*
* Source: https://iq.opengenus.org/leftist-heap/
*
*/
public class LeftistHeap {
private class Node {
private int element, npl;
private Node left, right;
// Node constructor setting the data element and left/right pointers to null
private Node(int element) {
this.element = element;
left = right = null;
npl = 0;
}
}
private Node root;
// Constructor
public LeftistHeap() {
root = null;
}
// Checks if heap is empty
public boolean isEmpty() {
return root == null;
}
// Resets structure to initial state
public void clear() {
// We will put head is null
root = null;
}
// Merge function that merges the contents of another leftist heap with the
// current one
public void merge(LeftistHeap h1) {
// If the present function is rhs then we ignore the merge
root = merge(root, h1.root);
h1.root = null;
}
// Function merge with two Nodes a and b
public Node merge(Node a, Node b) {
if (a == null)
return b;
if (b == null)
return a;
// Violates leftist property, so must do a swap
if (a.element > b.element) {
Node temp = a;
a = b;
b = temp;
}
// Now we call the function merge to merge a and b
a.right = merge(a.right, b);
// Violates leftist property so must swap here
if (a.left == null) {
a.left = a.right;
a.right = null;
} else {
if (a.left.npl < a.right.npl) {
Node temp = a.left;
a.left = a.right;
a.right = temp;
}
a.npl = a.right.npl + 1;
}
return a;
}
// Function insert. Uses the merge function to add the data
public void insert(int a) {
root = merge(new Node(a), root);
}
// Returns and removes the minimum element in the heap
public int extract_min() {
// If is empty return -1
if (isEmpty())
return -1;
int min = root.element;
root = merge(root.left, root.right);
return min;
}
// Function returning a list of an in order traversal of the data structure
public ArrayList<Integer> in_order() {
ArrayList<Integer> lst = new ArrayList<>();
in_order_aux(root, lst);
return new ArrayList<>(lst);
}
// Auxiliary function for in_order
private void in_order_aux(Node n, ArrayList<Integer> lst) {
if (n == null)
return;
in_order_aux(n.left, lst);
lst.add(n.element);
in_order_aux(n.right, lst);
}
}

View File

@ -0,0 +1,28 @@
package com.thealgorithms.datastructures.heaps;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class LeftistHeapTest {
@Test
void testLeftistHeap() {
LeftistHeap heap = new LeftistHeap();
Assertions.assertTrue(heap.isEmpty());
heap.insert(6);
Assertions.assertTrue(!heap.isEmpty());
heap.insert(2);
heap.insert(3);
heap.insert(1);
heap.in_order();
Assertions.assertTrue(heap.in_order().toString().equals("[6, 2, 3, 1]"));
Assertions.assertTrue(heap.extract_min() == 1);
Assertions.assertTrue(heap.in_order().toString().equals("[6, 2, 3]"));
heap.insert(8);
heap.insert(12);
heap.insert(4);
Assertions.assertTrue(heap.in_order().toString().equals("[8, 3, 12, 2, 6, 4]"));
heap.clear();
Assertions.assertTrue(heap.isEmpty());
}
}