Last active
January 25, 2022 18:38
-
-
Save Dimanaux/b6b3ecce5bcea62a10a3d65b4c646c42 to your computer and use it in GitHub Desktop.
Binomial heap java implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package datastructures; | |
import java.util.Comparator; | |
public class BinomailHeap<K extends Comparable> { | |
private Node<K> head; | |
private int size; | |
private Comparator<K> comparator; | |
public BinomailHeap() { | |
size = 0; | |
head = 0; | |
comparator = new Comparator<>() { | |
@Override | |
public int compare(K o1, K o2) { | |
return o1.compareTo(o2); | |
} | |
} | |
} | |
public int size() { | |
return size; | |
} | |
public K getMinumum() { | |
Node<K> min = head; | |
for (Node<K> current = head.sibling; current != null; current = current.sibling) { | |
if (comparator.compare(min.key, current.key) < 0) { | |
min = current; | |
} | |
} | |
return min.key; | |
} | |
private void merge(Node<K> otherHead) { | |
Node<K> ptrThis = head; | |
Node<K> ptrOther = otherHead; | |
Node<K> ptrNew = null; | |
if (ptrThis.degree < ptrOther.degree) { | |
ptrNew = ptrThis; | |
ptrThis = ptrThis.sibling; | |
} else { | |
ptrNew = ptrOther; | |
ptrOther = ptrOther.sibling; | |
} | |
head = ptrNew; | |
while (ptrThis != null && ptrOther != null) { | |
if (ptrThis.degree < ptrOther.degree) { | |
ptrNew.sibling = ptrThis; | |
ptrThis = ptrThis.sibling; | |
} else { | |
ptrNew.sibling = ptrOther; | |
ptrOther = ptrOther.sibling; | |
} | |
ptrNew = ptrNew.sibling; | |
} | |
ptrNew.sibling = ptrOther == null ? ptrThis : ptrOther; | |
} | |
public void merge(BinomailHeap<K> other) { | |
if (other.head == null) { | |
return; | |
} | |
this.size += other.size; | |
if (this.head == null) { | |
this.head = other.head; | |
return; | |
} | |
merge(other.head); | |
consolidate(); | |
} | |
private void consolidate() { | |
Node<K> previous = null; | |
Node<K> current = head; | |
Node<K> next = head.sibling; | |
while (next != null) { | |
if (next.degree != current.degree | |
|| next.sibling != null | |
&& current.degree == next.sibling.degree) { | |
previous = current; | |
current = next; | |
} else if (comparator.compare(current.key, next.key) > 0) { | |
current.sibling = next.sibling; | |
current.addNode(next); | |
} else { | |
if (previous == null) { | |
head = next; | |
} else { | |
previous.sibling = next; | |
} | |
next.addNode(current); | |
current = next; | |
} | |
next = current.sibling; | |
} | |
} | |
public void add(K key) { | |
Node<K> newNode = new Node<>(key); | |
newNode.sibling = head; | |
head = newNode; | |
size++; | |
consolidate(); | |
} | |
private Node<K> removeRoot(Node<K> root) { | |
Node<K> previous = null; | |
if (head != root) { | |
previous = head; | |
while (previous.sibling != root) { | |
previous = previous.sibling; | |
} | |
} | |
if (previous == null) { | |
head = root.sibling; | |
} else { | |
previous.sibling = root.sibling; | |
} | |
if (node.child != null) { | |
Node<K> rootList = null; | |
Node<K> child = root.child; | |
// for each child of root | |
while (child != null) { | |
Node<K> next = child.sibling; | |
child.sibling = rootList; | |
rootList = child; | |
child = next; | |
} | |
} | |
size--; | |
return root; | |
} | |
private Node<K> extractMinimumNode() { | |
if (head == null) { | |
return null; | |
} | |
Node<K> min = head; | |
for (Node<K> current = head.sibling; current != null; current = current.sibling) { | |
if (comparator.compare(current.key, min.key) >= 0) { | |
min = current; | |
} | |
} | |
return removeRoot(min); | |
} | |
public K extractMinimum() { | |
return extractMinimumNode().key; | |
} | |
public Node<K> changeKey(Node<K> node, K newKey) { | |
if (comparator.compare(newKey, node.key) < 0) { | |
throw new IllegalArgumentException("Priority cannot be changed."); | |
} | |
Node<K> current = node; | |
while (current.parent != null && comparator.compare(newKey, current.parent.key) > 0) { | |
current.key = current.parent.key; | |
current = current.parent; | |
} | |
current.key = newKey; | |
return current; | |
} | |
public Node<K> removeNode(Node<K> node) { | |
Node<K> current = node; | |
while (current.parent != null) { | |
current.key = current.parent.key; | |
current = current.parent; | |
} | |
return removeRootNode(current); | |
} | |
} | |
class Node<K> { | |
K key; | |
int degree; | |
Node<K> parent = null; | |
Node<K> sibling = null; | |
Node<K> child = null; | |
Node(K key) { | |
this(); | |
this.key = key; | |
} | |
Node() { | |
key = null; | |
degree = 0; | |
} | |
void addNode(Node<K> other) { | |
other.parent = this; | |
other.sibling = child; | |
child = other; | |
degree++; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Full of MISTAKES !! Don't upload codes without testing them yourself. Silly mistakes might be acceptable but mistakes in the algorithm implementation should make you ban in github.