import
java.util.*;
class
Node {
Node parent;
Node child;
Node left;
Node right;
int
key;
int
degree;
char
mark;
char
c;
}
class
GFG {
static
Node mini =
null
;
static
int
no_of_nodes =
0
;
static
void
insertion(
int
val)
{
Node new_node =
new
Node();
new_node.key = val;
new_node.degree =
0
;
new_node.mark =
'W'
;
new_node.c =
'N'
;
new_node.parent =
null
;
new_node.child =
null
;
new_node.left = new_node;
new_node.right = new_node;
if
(mini !=
null
) {
mini.left.right = new_node;
new_node.right = mini;
new_node.left = mini.left;
mini.left = new_node;
if
(new_node.key < mini.key)
mini = new_node;
}
else
{
mini = new_node;
}
no_of_nodes++;
}
static
void
Fibonnaci_link(Node ptr2, Node ptr1)
{
ptr2.left.right = ptr2.right;
ptr2.right.left = ptr2.left;
if
(ptr1.right == ptr1) {
mini = ptr1;
}
ptr2.left = ptr2;
ptr2.right = ptr2;
ptr2.parent = ptr1;
if
(ptr1.child ==
null
) {
ptr1.child = ptr2;
}
ptr2.right = ptr1.child;
ptr2.left = ptr1.child.left;
ptr1.child.left.right = ptr2;
ptr1.child.left = ptr2;
if
(ptr2.key < ptr1.child.key) {
ptr1.child = ptr2;
}
ptr1.degree++;
}
static
void
Consolidate()
{
int
temp1;
double
temp2
= (Math.log(no_of_nodes)) / (Math.log(
2
));
int
temp3 = (
int
)temp2;
Node[] arr =
new
Node[temp3 +
1
];
for
(
int
i =
0
; i <= temp3; i++) {
arr[i] =
null
;
}
Node ptr1 = mini;
Node ptr2;
Node ptr3;
Node ptr4 = ptr1;
do
{
ptr4 = ptr4.right;
temp1 = ptr1.degree;
while
(arr[temp1] !=
null
) {
ptr2 = arr[temp1];
if
(ptr1.key > ptr2.key) {
ptr3 = ptr1;
ptr1 = ptr2;
ptr2 = ptr3;
}
if
(ptr2 == mini) {
mini = ptr1;
}
Fibonnaci_link(ptr2, ptr1);
if
(ptr1.right == ptr1) {
mini = ptr1;
}
arr[temp1] =
null
;
temp1++;
}
arr[temp1] = ptr1;
ptr1 = ptr1.right;
}
while
(ptr1 != mini);
mini =
null
;
for
(
int
j =
0
; j <= temp3; j++) {
if
(arr[j] !=
null
) {
arr[j].left = arr[j];
arr[j].right = arr[j];
if
(mini !=
null
) {
mini.left.right = arr[j];
arr[j].right = mini;
arr[j].left = mini.left;
mini.left = arr[j];
if
(arr[j].key < mini.key) {
mini = arr[j];
}
}
else
{
mini = arr[j];
}
if
(mini ==
null
)
mini = arr[j];
else
if
(arr[j].key < mini.key)
mini = arr[j];
}
}
}
static
void
Extract_min()
{
if
(mini ==
null
) {
System.out.println(
"The heap is empty"
);
}
else
{
Node temp = mini;
Node pntr;
pntr = temp;
Node x =
null
;
if
(temp.child !=
null
) {
x = temp.child;
do
{
pntr = x.right;
mini.left.right = x;
x.right = mini;
x.left = mini.left;
mini.left = x;
if
(x.key < mini.key) {
mini = x;
}
x.parent =
null
;
x = pntr;
}
while
(pntr != temp.child);
}
temp.left.right = temp.right;
temp.right.left = temp.left;
mini = temp.right;
if
(temp == temp.right && temp.child ==
null
) {
mini =
null
;
}
else
{
mini = temp.right;
Consolidate();
}
no_of_nodes--;
}
}
static
void
Cut(Node found, Node temp)
{
if
(found == found.right) {
temp.child =
null
;
}
found.left.right = found.right;
found.right.left = found.left;
if
(found == temp.child) {
temp.child = found.right;
}
temp.degree--;
found.right = found;
found.left = found;
mini.left.right = found;
found.right = mini;
found.left = mini.left;
mini.left = found;
found.parent =
null
;
found.mark =
'B'
;
}
static
void
Cascase_cut(Node temp)
{
Node ptr5 = temp.parent;
if
(ptr5 !=
null
) {
if
(temp.mark ==
'W'
) {
temp.mark =
'B'
;
}
else
{
Cut(temp, ptr5);
Cascase_cut(ptr5);
}
}
}
static
void
Decrease_key(Node found,
int
val)
{
if
(mini ==
null
) {
System.out.println(
"The Heap is Empty"
);
}
if
(found ==
null
) {
System.out.println(
"Node not found in the Heap"
);
}
found.key = val;
Node temp = found.parent;
if
(temp !=
null
&& found.key < temp.key) {
Cut(found, temp);
Cascase_cut(temp);
}
if
(found.key < mini.key) {
mini = found;
}
}
static
void
Find(Node mini,
int
old_val,
int
val)
{
Node found =
null
;
Node temp5 = mini;
temp5.c =
'Y'
;
Node foundPtr =
null
;
if
(temp5.key == old_val) {
foundPtr = temp5;
temp5.c =
'N'
;
found = foundPtr;
Decrease_key(found, val);
}
if
(foundPtr ==
null
) {
if
(temp5.child !=
null
) {
Find(temp5.child, old_val, val);
}
if
((temp5.right).c !=
'Y'
) {
Find(temp5.right, old_val, val);
}
}
temp5.c =
'N'
;
found = foundPtr;
}
static
void
Deletion(
int
val)
{
if
(mini ==
null
) {
System.out.println(
"The heap is empty"
);
}
else
{
Find(mini, val,
0
);
Extract_min();
System.out.println(
"Key Deleted"
);
}
}
static
void
display()
{
Node ptr = mini;
if
(ptr ==
null
) {
System.out.println(
"The Heap is Empty"
);
}
else
{
System.out.println(
"The root nodes of Heap are: "
);
do
{
System.out.print(ptr.key);
ptr = ptr.right;
if
(ptr != mini) {
System.out.print(
"-->"
);
}
}
while
(ptr != mini && ptr.right !=
null
);
System.out.println();
System.out.println(
"The heap has "
+ no_of_nodes
+
" node"
);
System.out.println();
}
}
public
static
void
main(String[] args)
{
System.out.println(
"Creating an initial heap"
);
insertion(
5
);
insertion(
2
);
insertion(
8
);
display();
System.out.println(
"Delete the node 8"
);
Deletion(
8
);
System.out.println(
"Delete the node 5"
);
Deletion(
5
);
display();
}
}