Structure

To keep the desired time complexities as described in the Operation section, there are still some details that we need to pay attention to:

The design below is one possible structure suggested in the paper by using pointers only(see reference). Note this is not the only possible design, and below is intended to provide a general idea of how the above key points are possible

Structure In the Paper

Fix-List

This is what makes finding Active Root Reduction and Loss Reduction in O(1) possible. We maintain a Fix-List in which it contains a linked-list of active nodes that could potentially perform the transformations. We divided it into 4 parts.

If we need to perform an Active Root Reduction, we just need to check if part 1 is non-empty. If a reduction is performed, one node becomes an active node with loss 0, so it's removed from this list. And another node's rank is increased by 1, so we just need to go to the Rank-List(described below), and follow the pointer to the correct position in the Fix-List.

If we need to perform a One or Two Nodes Loss Reduction, we just need to check if part 4 is non-empty. If a One Node Loss Reduction is performed, the target node becomes an active root, so it may need to move to part 1 or 2 -- by just following the pointer in the Rank-List. If a Two Node Loss Reduction is performed, both nodes become active nodes with loss 0, so they will be removed from the Fix-List, and we need to check if there is one remaining node with the same rank and loss 1 still in the Fix-List, if so, it should be moved to part 3.

In summary, by maintaining a Fix-List, an Active Root Reduction or Loss Reduction can be found in O(1) time. And after the reduction, some nodes may need to move, but all these can be checked and done in O(1) trivially by following the pointers. Also trivially, because of the structure, nodes for Root Degree Reduction can be found by checking the root's last 3 children.

Rank-List

We maintain a Rank-List in which it contains R + 1 nodes(as R is the maximum rank), each represents rank 0, 1, 2, ...R, as a linked list.

The node represents rank r in the Rank-List has a pointer to the first active root with rank r in part 1 or 2 of the Fix-List, and a pointer to the first active node with rank r and positive loss in part 3 or 4 of the Fix-List. As explained above, these two pointers allow the transfer of nodes in the Fix-List to be done in O(1)

Node

Heap

Every heap maintains its own Rank-List, Fix-List, root, Q, an active flag, and a pointer to the first passive child of the root(so we can insert a passive non-linkable child to the root in O(1) when decreasing key). When a merge happens, all nodes in the smaller heap become passive, so the new Rank-List and Fix-List is just the larger size heap. All active nodes in the same heap point to the same TRUE active flag that the heap has. And to make all nodes in a heap passive in O(1), we just need to change the active flag to FALSE. A node is considered to be active if and only if it's pointing to a TRUE active flag. A node is passive if it's pointing to null or a FALSE active flag e.g.


The analysis on this site is based on Strict Fibonacci Heaps