import
java.util.ArrayList;
import
java.util.List;
class
Node {
int
val, degree;
Node parent, child, sibling;
}
class
BinomialHeap {
private
Node root;
public
BinomialHeap() {
this
.root =
null
;
}
private
void
binomialLink(Node h1, Node h2) {
h1.parent = h2;
h1.sibling = h2.child;
h2.child = h1;
h2.degree = h2.degree +
1
;
}
private
Node createNode(
int
n) {
Node new_node =
new
Node();
new_node.val = n;
new_node.parent =
null
;
new_node.sibling =
null
;
new_node.child =
null
;
new_node.degree =
0
;
return
new_node;
}
private
Node mergeBHeaps(Node h1, Node h2) {
if
(h1 ==
null
)
return
h2;
if
(h2 ==
null
)
return
h1;
Node res;
if
(h1.degree <= h2.degree)
res = h1;
else
res = h2;
while
(h1 !=
null
&& h2 !=
null
) {
if
(h1.degree < h2.degree)
h1 = h1.sibling;
else
if
(h1.degree == h2.degree) {
Node sib = h1.sibling;
h1.sibling = h2;
h1 = sib;
}
else
{
Node sib = h2.sibling;
h2.sibling = h1;
h2 = sib;
}
}
return
res;
}
private
Node unionBHeaps(Node h1, Node h2) {
if
(h1 ==
null
&& h2 ==
null
)
return
null
;
Node res = mergeBHeaps(h1, h2);
Node prev =
null
, curr = res, next = curr.sibling;
while
(next !=
null
) {
if
((curr.degree != next.degree) || ((next.sibling !=
null
) && (next.sibling).degree == curr.degree)) {
prev = curr;
curr = next;
}
else
{
if
(curr.val <= next.val) {
curr.sibling = next.sibling;
binomialLink(next, curr);
}
else
{
if
(prev ==
null
)
res = next;
else
prev.sibling = next;
binomialLink(curr, next);
curr = next;
}
}
next = curr.sibling;
}
return
res;
}
public
void
binomialHeapInsert(
int
x) {
root = unionBHeaps(root, createNode(x));
}
private
void
display(Node h) {
while
(h !=
null
) {
System.out.print(h.val +
" "
);
display(h.child);
h = h.sibling;
}
}
private
Node revertList(Node h) {
if
(h.sibling !=
null
) {
revertList(h.sibling);
(h.sibling).sibling = h;
}
else
root = h;
return
root;
}
private
Node extractMinBHeap(Node h) {
if
(h ==
null
)
return
null
;
Node min_node_prev =
null
;
Node min_node = h;
int
min = h.val;
Node curr = h;
while
(curr.sibling !=
null
) {
if
((curr.sibling).val < min) {
min = (curr.sibling).val;
min_node_prev = curr;
min_node = curr.sibling;
}
curr = curr.sibling;
}
if
(min_node_prev ==
null
&& min_node.sibling ==
null
)
h =
null
;
else
if
(min_node_prev ==
null
)
h = min_node.sibling;
else
min_node_prev.sibling = min_node.sibling;
if
(min_node.child !=
null
) {
revertList(min_node.child);
(min_node.child).sibling =
null
;
}
else
root =
null
;
return
unionBHeaps(h, root);
}
private
Node findNode(Node h,
int
val) {
if
(h ==
null
)
return
null
;
if
(h.val == val)
return
h;
Node res = findNode(h.child, val);
if
(res !=
null
)
return
res;
return
findNode(h.sibling, val);
}
private
void
decreaseKeyBHeap(Node H,
int
old_val,
int
new_val) {
Node node = findNode(H, old_val);
if
(node ==
null
)
return
;
node.val = new_val;
Node parent = node.parent;
while
(parent !=
null
&& node.val < parent.val) {
int
temp = node.val;
node.val = parent.val;
parent.val = temp;
node = parent;
parent = parent.parent;
}
}
public
void
binomialHeapDelete(
int
val) {
if
(root ==
null
)
return
;
decreaseKeyBHeap(root, val, Integer.MIN_VALUE);
root = extractMinBHeap(root);
}
public
static
void
main(String[] args) {
BinomialHeap heap =
new
BinomialHeap();
heap.binomialHeapInsert(
10
);
heap.binomialHeapInsert(
20
);
heap.binomialHeapInsert(
30
);
heap.binomialHeapInsert(
40
);
heap.binomialHeapInsert(
50
);
System.out.println(
"The heap is:"
);
heap.display(heap.root);
heap.binomialHeapDelete(
10
);
System.out.println(
"\nAfter deleting 10, the heap is:"
);
heap.display(heap.root);
}
}