Add Leftist Heap (#3789)
Co-authored-by: Adrian Paras <aparas@terpmail.umd.edu>
This commit is contained in:
parent
6a0035d872
commit
9123474729
@ -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);
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user