Actually the worst case bounds were previously achieved by G. S. Brodal  unfortunately with rather wide heap and complicated maintainance reflected in big multiplication constants making them impractical. I will call heaps from the paper  BLT heaps as their connection to Fibonacci is only negligable. The BLT heaps are narrow and they are trying to avoid unnecessary organization as much as possible. Our main goal is to implement heaps interface.
In Fibonacci Heaps  the method is internally used so it’s for free to make it in the heap interface. On the contrary, is not natural for the BLT heaps so implementing it requires a bit of structural overhead. Authors of  shown, it could be done without changing assymptotical behaviour of the data structure. We will show, our strategy is able to do it as well if really necessary. I don’t know an algorithm where operation is required so I expect for most applications the simplified interface and simplified implementation would be prefered choice.
In the BLT heaps are two main tricks to allow worst case complexities in the heaps. One is concerning decrement of the heap size during sequence of s where the time bounds should reflect current . When node neighbourhood in heap need to have shape bounded by a function , the decrease of means we should recheck all the nodes regularly. They have introduced a global list of heap nodes (just heap root is held separately) and after each decrement of , 2 first nodes are rechecked and moved to the list end. As the bound is logarithmic (), we could check all nodes before the bound is decremented by . They have found nice describtion of this by using rather to for bounding function of -th node on the list. With this trick the bound remain constant for all nodes except those we are checking and it is at least . The bound for nodes we are checking changes from resp. to resp. having difference either or . So planning degreee reduction by at least and doing it to extend as possible would maintain the degree constraints. We would need this trick for including version as well, but no such complication would be required for the simplified version.
The other trick is not trying to be too pedantic on the heap structure. They allow some violations of idealistic heap shape, but they remember the violations classified by their type and rank of node it affected. Violations of each type could be easily solved if we have at least two nodes of the same rank with this type of violation. So whenever operation introduces new violation of given type, violation reduction for this type is called. Either set of nodes with the type of violation is small or there are nodes of same rank allowing violation size reduction in constant time. Therefore this system maintains the violation size naturally bounded. Actually solving one type of violation may introduce violation of another type, but there is a linear function with small integer multiplicative constants combining violations sizes of all types, such that each violation reduction step decrements the function value whenever violation sizes are above their equilibrium values. As the function is growing only by a constant per increase in a coordinate, only constant number of violation reduction steps is required (and could be easily planned) to maintain the violation sizes of all the violations not exceeding their equilibrium values.
The BLT paper needed to show the ranks are limited by some function when each violation size is bounded by and . They got be the bigger root of quadratic polynomial defined by , it is easily bounded by , but even
would suffice. The same bound would apply to our heaps. Using estimateso gives plan to reduce degree of checked nodes by 2 for BLT heaps.
2 Analysis of worst case heaps requirements
Unfortunately, word active is used in citations in three different meanings, so we rather decided not use the word active in connection with our heaps at all. This is why I would use deffered/solid in meaning pasive/active from . Active in  is connected with parent pointer reduction what we are not concerned now. Active in  is connected with rank/nonrank links which are called fair/naïve there. There is another incompatibility among cited papers. In Padovan heaps the join of two roots of the same rank adds rightmost child making rank edge, while comparison of roots of different rank is reflected by adding leftmost child by a nonrank edge. The children order in  is reversed. The order in Padovan heaps differs from the choice from , let us make it compatible. So joining two roots of the same rank would result in adding leftmost child making rank edge while the nonrank edges would be added rightmost. Actually the children node order of solid children is not important and in the case of interface including , it is better to keep right side for deffered nodes, so even nonrank links of solid nodes would add leftmost child.
We would call solid node without parent connected by a rank edge a rank root. It would be compatible with solid(active) roots of a variant mentioned at the end of , but it differs from the main variant where active roots are defined by not having active parent and node with minimum key is kept passive, while it would be solid in our structure.
We would choose another path to reach the worst case bounds, but the high level describtion of the ideas would remain same. We would start with our amortised analysis of heaps based on superexpensive comparison principles and we would change the implementation in such a way the potencial changes would be proportional to the method times. One point of view is the potential is needless, but my point of view is natural potential still navigates us to better overall efficiency.
Let me rely on the amortized analysis of heaps based on superexpensive comparison principle from . We have potential representing number of trees (to pay for first phase of FindMin). It must decrease to during FindMin, and time of FindMin should be so we have to maintain number of trees constant. Calling FindMin after each update in the data structure would suffice.
We have potential corresponding to sum of differences of node degrees and their ranks. is used in DeleteMin to pay for increase of exceeding (corresponding to maximal possible rank). Actually having child deeper in the tree means longer the node neednot be compared to minimum. This is why we don’t want to cut those children unless necessary. Instead we change the definition of which would be good enough for its purpose as well. (As in BLT heaps we define bound function , let us fix the constants later. Let us use the global list defining positions of nodes and let us check first 2 nodes after each DeleteMin and move them to the list end. We can define corresponding to sum of (positive) diferences of node degrees and their bounds .) Even new definition of is sufficient to pay for increase during DeleteMin exceeding . Maintanance of would be rather easy.
We have potential corresponding to number of trees, but at most (to pay for second phase of FindMin). Maintaining constant forces be constant as well.
Last potential is corresponding to number of nodes whose rank was decremented from the time it was linked to its parent. The strategy of Fibonacci heaps was rank could be decremented at most once (creating loss of node at most 1) and further decrement should result in decrementing parent rank and making the edge nonrank edge. In the worst case scenario we cannot maintain the loss at most 1 and bound the rank consolidation to constant time simultaneously. Instead we would allow loss bigger than 1 so becomes sum of losses. We would maintain bounded by a logarithmic function, but we should prove the trees remain narrow for some and . Minimal size of rank subtree with root of rank and total loss in subtree at most is as well as in BLT heaps achived by tree with losses exactly at subtree root children which can be created by starting with binomial tree and times cutting grandchild of currently maximal rank. This therefore leads to the same quadratic equation and the same upper bound for and is sufficient for our purposes.
In amortized heaps the main work is done in FindMin where we temporarily use same rank identifying places. If we would maintain just one tree after each operation, there would be rarely incentive to create rank edges if we continue using this strategy. Instead we would maintain roots in the same rank identifying places for later use even after they are linked to other nodes by nonrank edges. This goes against superexpensive comparison principle as we would later compare root keys which cannot be minimal, but the creation of rank edges have higher priority (in the worst case environment). The same root identifying places become violation list of rank roots. Actually we will see later that in the case of interface we would need two violation lists of rank roots. As the rank identifying places are not dealocated, each heap needs to keep it private. This is why each heap would maintain its own list of ranks. We would make a compromise during FindMins. We would make violation lists reductions paid as much as allowed by decrease (correspondnig to the first phase of amortised version), than we would make nonrank links as in the second phase of amortised version. Making nonrank links first and than do violation reductions would achieve same assymptotic bahaviour, but it would make more comparisons. Internally FindMin would process list of tree roots, the roots will have parent pointer implicitly null. FindMin makes the parent pointeres of all the roots explicit.
3 Violations and their reductions
|node degree reduction|
|reduction step (A)|
|- no 3 deffered chidren|
|- 3 deffered children reduced|
|reduction step (G)|
|reduction step (L)|
|- one node, parent was rank root in or|
|- one node, parent allready had loss > 0|
|- one node, parent no 3 deffered children > 0|
|- one node, parent 3 deffered children reduced|
|- two nodes, parent of is rank child|
|- two nodes, parent of in|
|- two nodes, parent of in|
Deffered nodes would be made by the method. Similarly as in BLT heaps, the nodes of smaller heap would become deffered implicitly. Implicitly deffered nodes cannot have solid children. Deffered nodes would be accessed during degree reductions of their parents, and during DeleteMins, when the heap root was deffered node parent or by degree reduction of the deffered node reflecting decrease of heap size when moved from the start of heap node list to its end. When the implicitly deffered node is firstly accessed, the pointer responsible for implicit deffering is removed and the node is converted to explicitly deffered. Its rank pointer is redirected to the rank 0 of current heap. All its children are deffered (either implicitly or explicitly) in this time, so there are rightmost. Explicitly deffered nodes should have rank 0, so no solid rank child is allowed, but nonrank solid children are allowed.
As in BLT heaps, for the solid nodes with 0 loss the degree bound is one higher than for all other nodes. Degree reduction step on a node would be made similarly as root degree reduction on BLT heaps. If node is implicitly deffered, it is converted to explicitly deffered. If the rightmost 3 children are deffered, we convert them to explicitly deffered if not converted yet and we remove them from children list of . We made 3 comparisons to find order of their keys (again against the superexpensive comparisons principle) let node have the smallest, the middle, and the highest key. We continue by making and solid. We create rank edge making root of rank 1 having solid rank child of rank 0. We make a deffered child of , whose rank would stay 0. Finaly is linked as a nonrank (leftmost) child of . Degree constraints are OK for and as they become solid with loss 0. New rank root without guaranted degree reserve was created. Degree of was reduced by 2.
Rank roots without guaranted reserve would be maintained in violation list allowing fast localisation of two nodes of the same rank if they exist in the list. Similarly active roots with guaranted reserve would be maintained in violation list allowing fast localisation of two nodes of the same rank if they exist in the list.
If was a rank root and it’s rank is decremented, we know now it has guaranted reserve, so decrement of its rank could remove it from and add to .
If there are two nodes of the same rank on violation list reduction step could be applied. It links two nodes of the same rank. (Their keys are compared, let node be the one with smaller key while the other. We cut from its parent (nonrank edge) and put it as a rank child of . This increases rank of as well as it’s degree. Degree reduction is performed on what makes active root with guaranted reserve ( is enough to guareantee the degree reduction occures when there is no reserve). So both and are removed from and the active root possibly created by the degree reduction would be added to . Node is added to .)
If there are two nodes of the same rank on violation list reduction step could be applied. It links two nodes of the same rank. (Their keys are compared, let node be the one with smaller key while the other. We cut from its parent (nonrank edge) and put it as a rank child of . This increases rank of as well as it’s degree. Degree reduction is not performed on as there was degree reserve. So both and are removed from and is added to .)
As in BLT heaps we would maintain violation list of nodes with positive loss organized in a way nodes of the same rank in the list would be easily detected (as well as nodes with loss bigger than 1). The loss reduction takes node with loss at least 2, it makes it nonrank child of it’s parent . This creates new rank root (with loss 0 and guaranted degree reserve). The rank of is decremented and if is a rank child, its loss is increased and new loss violation is added, but total loss was reduced by at least 1. Degree of could have been on it’s limit and the limit was decremented if the loss changed from 0 to 1, therefore degree reduction should be called on the parent if it changed loss from 0 to 1. If was a rank root, it has to be reinserted to the same violation list it was before the rank decrement as both limit and degree did not changed. Alternatively we take two nodes with loss 1 of the same rank and link them. (Their keys are compared, let and be the nodes with higher and smaller keys respectively. Remove from it’s parent and link it under by a rank edge. This reduces loss of to 0 and sets loss of to 0. Original parent of decrements rank by 1, so if as a rank child new loss violation is introduced, but the total loss was reduced by at least 1. Degree constraint for is OK as well as for . If was rank root, it got degree reserve so it should be inserted to during the rank decrement.)
In table 1 you can see the effect of reductions, when they take place (otherwise the bounds are not exceeded and reduction is not required).
So if , , could be increased by an operation by , , respectively, we could make violation list reductions, violation list reductions and violation list reductions. See the table 2. This would return each of , , to either original value or to be at most maximal rank + 1 (no two items in the list with the same rank, no nodes with loss exceedenig 1). These reductions should be done to extend as possible (if any planned is possible do it, if no planned is possible you could stop) similarly as in BLT heaps.
Degree reduction gives us equilibrium bounds for node degrees providing maximal rank is and all violation lists sizes do not exceed . The node could have at most rank children, at most nonrank children of violation list , at most nonrank children of violation list and at most 2 deffered children. If it has more children, degree reduction can be performed. For our analysis it would be fine to define for solid nodes with loss 0 and for other nodes (with being position in the global list of nodes). (In BLT paper the bound is just as there is only one violation list of active roots and passive nodes have rank 0 and active nodes have no nonrank active children.) With estimate we got so and we have to plan degree reduction by 4, what corresponds to planning two degree reduction steps for a checked node.
As in BLT heaps, linking of rank roots which are nonrank children introduces situation which cannot happen when comparing only tree roots. In the case keyes could be equal, random choice of result would allow chosing to be predecessor of resulting in broken tree and a cycle. To prevent this we should expect keys are all different. If this is not guaranted from outside, solution is to generate (different) id’s for key nodes and broke ties by id’s comparisons.
4 Heap structure
Heap information contains size of heap (node count initialised to 0), pointers to start of rank list, to list of heap tree roots, to violation lists , , and to the list of all heap nodes. All the lists are maintained double linked, left pointers are maintaned cyclic (left of leftmost points to rightmost). This allows access of both ends in constant time as well as adding or removing of a given node. Violation list node has its own left and right pointers and is interconnected by pointers with represented heap node. List of heap tree roots uses sibling pointers maintained in the heap nodes. All heap nodes could have pointers internally in heap nodes as well.
A rank list node contain reference counter, pointer to the heap information and pointers , , and to violation lists , , respectively. Assigning node rank 0 means setting pointer to the start of the rank list. Ranks are never set to other value, there are only incremented or decremented, what means setting pointer to the corresponding neighbour in the rank list. With each rank change reference counters are updated. If needed, list is extended. We increment reference counter of the previous end of the list when it happens. Whenever reference counter on (last) node on the list returns to 0, we shorten the list, what decrements reference counter of new list end. When the rank 0 reference counter is 0 at the same time as heap size , the heap information is discarded.
Whether the node is rank child, nonrank child or explicitly deffered is maintained in the node state, but this is overriden by being a heap tree root or being implicitly deffered.
Each node which points through rank node to heap information with size is implicitly deffered. It could be made explicitly deffered by removal from a violation list it (possibly) appears at, setting corresponding state and setting rank to 0 by pointing to current heap rank list start (the reference counter for original rank should be decremented as well). The removal from a violation list of implicitly deffered nodes neednot organize the violation lists by ranks, so trivial removal suffices.
Whenever node is inserted to violation list of given type , violation list node pointing back to is created. Pointer back from to could be required later. We could use rank pointer in to save space, but in that case it should be saved in and restored when is removed from the violation list. Placing into the list requires some care. If pointer for corresponding rank list node is null, it is replaced by pointer to and is added to left end of violation list of type . However if pointer is not null, we have at least two nodes of the rank in the violation list. We check existence of a neighbour of of the same rank. If it does not exist, we move to the right end of the violation list of type . Than (in both cases), we add to the right of .
Whenever we remove node from the violation list, we check if points to . If points to and its right neighbour has the same rank, we let point to the neighbour (otherwise we set it to null). Than is removed from the list and if is not null it’s right neighbour is checked to have same rank. If it has the same rank, we are done. Otherwise node should be removed and inserted (to the list left end). This strategy guarantees if two nodes of the same rank exists in the list, such pair can be found on its right end. There is slight exception in violation list of type , where nodes of loss at least 2 are not organized by rank. They are simply put to the right end and eventually removed without other changes in the list.
5 Implementation of methods
We will describe the methods using private blocks. Their use could be slightly optimized (for example replacing pointer with null immediately before (never accessed pointer) replacing by other value could be avoided, adding node to a violation list when it will be removed from it in the same method could be avoided as well). Decomposition into blocks makes the description easier.
Before a public method is called, the violation list sizes are at most where is maximal possible rank. Whenever violation list size is changed during a method, we remember the change. FindMin adds to plan enough violation reductions and performes planned reductions to the extend possible to restore the list sizes to be each at most , as was described in the previous two sections. Each other public method calls FindMin and does not introduce new violations after the return.
Similarly as in BLT heaps whenever we decrement size of the heap, we two times remove first node of the list of heap nodes (if it exists), we make two degree reductions on and put to the end of the list. This makes the degree constraints to hold for all nodes of the heap (assuming they have held prior to the decrement).
Whenever we decrement rank of a node , violation list should be made up to date. We should know if decrement is done by ) rank child removal or ) rank child conversion to nonrank child. In the case is rank root, it must have been in either or violation list. It should be removed from the violation list and added to position corresponding to decremented rank in ) violation list if the degree was reduced ) to the same violation list it was before if the degree was preserved. In the case is not rank root, it’s loss is increased. If loss of becomes 1, it is put to violation list according it’s rank. If the loss was 1, it is removed from position corresponding to the original rank and it is added among nodes with loss at least 2. Only in the case loss of was at least 2, the increment of loss is not reflected in change on a violation list.
Whenever we increment rank of a rank root , it must have been in either or violation list. It should be removed from the violation list and added to position corresponding to incremented rank in the other violation list. If it was in , it is added to and increment ends. If it was in , it is added to and degree reduction on is called, what finishes the rank increment.
Removal of a child of parent means following: In all cases the parent pointer of would be set to null and would be removed from the children list of and added to the list of heap tree roots. If was a rank child, rank of is decremented111by the already described method.
To link two solid nodes means comparing their keys, let node be the one with smaller key while the other. If had no parent, it is simply removed from its sibling list. Otherwise removal of a child of its parent is invoked. If was rank root, it is removed from the violation list or it was in. Node is added as a solid (therefore as leftmost) child of marking rank child if the nodes had equal rank and nonrank otherwise. If a rank child was added, rank of should be incremented.
MakeHeap inicializes the heap structure.
Insert() creates new solid node with key , rank 0, no parent and no child. It increments the heap size in the heap information without side effects. It adds as a new root to the list of heap tree roots and invokes FindMin. is returned for further references.
FindMin traverses nodes of heap tree roots list and makes their parent pointers explicitly to null. It counts the roots meanwhile and converts implicitly deffered roots to explicitly deffered and (even new) explicitly deffered to solid, the newly solid roots are added to violation list . A root which was already solid is checked to be in either or violation lists. If not, it is inserted to the violation list . Let there were roots. Add to plan violation list reductions and violation list reductions and do reductions to extend as possible. This finishes the first phase. As , , could be increased by FindMin by , , respectively, with , the violation sizes would remain in bounds. Than traverse the heap tree roots leftwise linking two neighbouring roots interlaced with steps to left in the circular list (to link the roots as even as possible). The phase ends when only one tree remains. It’s root points to minimum and it will be returned. All violations created during second phase should create new plan of violation reductions and that plan should be done to extend as possible before the return.
DeleteMin decrements size in the heap information. Let be the only tree root. It updates pointer to the list of roots to point to the leftmost child of . It removes from list of heap nodes and from the violation list it is contained in. It updates reference count in it’s rank. At the end it calls FindMin and discards .
(, ) removes from its parent if such parent exists. Than in all cases it updates key at node to . It invokes FindMin at the end. (We could maintain keys directly in the heap nodes rather to solution in BLT heaps where separate key nodes interlinked with heap nodes are proposed).
(, ) identifies smaller heap and larger by comparing sizes in the heap informations (call with a heap with size is invalid). It appends list of nodes to start of the list of nodes (and sets corresponding pointer at to null). As position nodes of in the new list remain same, but the heap size at least doubles, increases by so we got reserve 1 in degree bounds so we could make solid node with loss 0 of deffered node of without violating degree constraint bounds (for other nodes of it is even more obvious). It stores sum of the sizes in the heap informations and sets size to in informations, what makes all nodes implicitly deffered. It appends roots of trees list of to the front of roots of trees list of (and sets them to null in ). Finally it invokes FindMin and returns as a current heap.
6 Simplification when is not needed
As deffered nodes are created only by method, there will be no deffered nodes in the heap at all. Therefore all nonrank nodes will be rank roots. Their number is limited by their maintenance in violation lists by . This makes bounded by as well as each node degree. The degree reduction is impossible and it is not needed at all, all nodes have implicitly degree reserve, so there is no need to maintain rank roots in two different violation lists and one violation list say suffices. As deffered nodes would not be introduced, there is no need for structure supporting implicit deffering with reference counts to allow dealocation of its parts. The global node list to organize degree reductions is not needed as well. So the only support needed are the two volation lists and . If there are no deffered nodes, I would prefere inserts of nonrank nodes rather to right end of children lists for aesthetic reasons.
|reduction step (A)|
|reduction step (L)|
|- one node, parent was rank root|
|- one node, parent was not rank root|
|- two nodes|
7 Concluding remarks
There is rather big overhead in organizing violation lists by ranks. I would recomend slightly different strategy then described so far. When new violation is added to the violation list, plan to do violation reductions steps is updated. If there is exactly one node of the same rank in the list, I would rather made planned violation reduction step immediately rather to reorganization of the list. Of course the violations created by the reduction steps should not affect the plans and when there are no more violation reductions planned we could be forced to create new pair of violating nodes of the same rank in the violation list so moving them to the right end. I bet this caching of creating violation list nodes and of moving pairs to right end would reduce the overhead significantly.
We have shown a variant of worst case heaps not losing information by repeated linking of heap nodes under the heap roots could be implemented. It is simpler than the main variant presented in BLT heaps according some aspects, but complicated in other aspects. (No need for separation of keys from nodes, we bet to have better optimized number of comparisons in amortized sense. Main drawback is we need 3 violation lists rather to 2, and because we have allowed nonrank children even to nodes with high rank, the children list size upperbound become roughly 3 times higher than those of the BLT ones, fortunately it is sufficient to do at most 2 rank reduction steps in two checked nodes to compensate for heap size decrement. The bigger upper limit for number of children is compensated in minimizing comparisons not reflected in heap edges.)
For the interface without two violation lists are sufficient. The only remaining drawback is the worstcase bounds for degrees are roughly twice the bounds of the BLT heaps. The main advantage is the bounds are maintained implicitly and no global list with overhead of node bound checking is required at all.
For the worst case interface of heaps (without ) these are the fastest and simplest published heaps so far (according to my current knowledge).
-  Gerth Stølting Brodal. Worst-case efficient priority queues. In Proceedings of the Seventh Annual ACM-SIAM Symposium on Discrete Algorithms, SODA ’96, pages 52–58, Philadelphia, PA, USA, 1996. Society for Industrial and Applied Mathematics. URL: http://dl.acm.org/citation.cfm?id=313852.313883.
Gerth Stølting Brodal, George Lagogiannis, and Robert E. Tarjan.
Strict fibonacci heaps.
Proceedings of the Forty-fourth Annual ACM Symposium on Theory of Computing, STOC ’12, pages 1177–1184, New York, NY, USA, 2012. ACM. URL: http://doi.acm.org/10.1145/2213977.2214082, doi:10.1145/2213977.2214082.
-  Michael L. Fredman and Robert Endre Tarjan. Fibonacci heaps and their uses in improved network optimization algorithms. J. ACM, 34(3):596–615, July 1987. URL: http://doi.acm.org/10.1145/28869.28874, doi:10.1145/28869.28874.
-  Haim Kaplan, Robert Endre Tarjan, and Uri Zwick. Fibonacci heaps revisited. CoRR, abs/1407.5750, 2014. URL: http://arxiv.org/abs/1407.5750, arXiv:1407.5750.
-  Vladan Majerech. Padovan heaps. CoRR, abs/1902.10812, 2019. URL: http://arxiv.org/abs/1902.10812, arXiv:1902.10812.