Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Binomial heap
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Implementation == Because no operation requires random access to the root nodes of the binomial trees, the roots of the binomial trees can be stored in a [[linked list]], ordered by increasing order of the tree. Because the number of children for each node is variable, it does not work well for each node to have separate links to each of its children, as would be common in a [[binary tree]]; instead, it is possible to implement this tree using links from each node to its highest-order child in the tree, and to its sibling of the next smaller order than it. These sibling pointers can be interpreted as the next pointers in a linked list of the children of each node, but with the opposite order from the linked list of roots: from largest to smallest order, rather than vice versa. This representation allows two trees of the same order to be linked together, making a tree of the next larger order, in constant time.<ref name="clrs" /><ref name="brown" /> === Merge === [[File:Binomial heap merge1.svg|thumb|200px|To merge two binomial trees of the same order, first compare the root key. Since 7>3, the black tree on the left (with root node 7) is attached to the grey tree on the right (with root node 3) as a subtree. The result is a tree of order 3.]] The operation of '''merging''' two heaps is used as a subroutine in most other operations. A basic subroutine within this procedure merges pairs of binomial trees of the same order. This may be done by comparing the keys at the roots of the two trees (the smallest keys in both trees). The root node with the larger key is made into a child of the root node with the smaller key, increasing its order by one:<ref name="clrs" /><ref name="brown" /> '''function''' mergeTree(p, q) '''if''' p.root.key <= q.root.key '''return''' p.addSubTree(q) '''else''' '''return''' q.addSubTree(p) [[File:Binomial heap merge2.svg|thumb|300px|This shows the merger of two binomial heaps. This is accomplished by merging two binomial trees of the same order one by one. If the resulting merged tree has the same order as one binomial tree in one of the two heaps, then those two are merged again.]] To merge two heaps more generally, the lists of roots of both heaps are traversed simultaneously in a manner similar to that of the [[merge algorithm]], in a sequence from smaller orders of trees to larger orders. When only one of the two heaps being merged contains a tree of order <math>j</math>, this tree is moved to the output heap. When both of the two heaps contain a tree of order <math>j</math>, the two trees are merged to one tree of order <math>j+1</math> so that the minimum-heap property is satisfied. It may later become necessary to merge this tree with some other tree of order <math>j+1</math> in one of the two input heaps. In the course of the algorithm, it will examine at most three trees of any order, two from the two heaps we merge and one composed of two smaller trees.<ref name="clrs" /><ref name="brown" /> '''function''' merge(p, q) '''while''' '''not''' (p.end() '''and''' q.end()) tree = mergeTree(p.currentTree(), q.currentTree()) '''if''' '''not''' heap.currentTree().empty() tree = mergeTree(tree, heap.currentTree()) heap.addTree(tree) heap.next(); p.next(); q.next() Because each binomial tree in a binomial heap corresponds to a bit in the binary representation of its size, there is an analogy between the merging of two heaps and the binary addition of the ''sizes'' of the two heaps, from right-to-left. Whenever a carry occurs during addition, this corresponds to a merging of two binomial trees during the merge.<ref name="clrs" /><ref name="brown" /> Each binomial tree's traversal during merge only involves roots, hence making the time taken at most order <math>\log_2 n</math> and therefore the running time is <math>O(\log n)</math>.<ref name="clrs" /><ref name="brown" /> === Insert === '''Inserting''' a new element to a heap can be done by simply creating a new heap containing only this element and then merging it with the original heap. Because of the merge, a single insertion takes time <math>O(\log n)</math>. However, this can be sped up using a merge procedure that shortcuts the merge after it reaches a point where only one of the merged heaps has trees of larger order. With this speedup, across a series of <math>k</math> consecutive insertions, the total time for the insertions is <math>O(k+\log n)</math>. Another way of stating this is that (after logarithmic overhead for the first insertion in a sequence) each successive '''insert''' has an [[Amortized time|''amortized'' time]] of <math>O(1)</math> (i.e. constant) per insertion.<ref name="clrs" /><ref name="brown" /> A variant of the binomial heap, the [[skew binomial heap]], achieves constant worst case insertion time by using forests whose tree sizes are based on the [[skew binary number system]] rather than on the binary number system.<ref>{{citation | last1 = Brodal | first1 = Gerth Stølting | last2 = Okasaki | first2 = Chris | date = November 1996 | doi = 10.1017/s095679680000201x | issue = 6 | journal = Journal of Functional Programming | pages = 839–857 | title = Optimal purely functional priority queues | volume = 6| doi-access = free }}</ref> === Find minimum === To find the '''minimum''' element of the heap, find the minimum among the roots of the binomial trees. This can be done in <math>O(\log n)</math> time, as there are just <math>O(\log n)</math> tree roots to examine.<ref name="clrs" /> By using a pointer to the binomial tree that contains the minimum element, the time for this operation can be reduced to <math>O(1)</math>. The pointer must be updated when performing any operation other than finding the minimum. This can be done in <math>O(\log n)</math> time per update, without raising the overall asymptotic running time of any operation.{{cn|date=October 2019}} === Delete minimum === To '''delete the minimum element''' from the heap, first find this element, remove it from the root of its binomial tree, and obtain a list of its child subtrees (which are each themselves binomial trees, of distinct orders). Transform this list of subtrees into a separate binomial heap by reordering them from smallest to largest order. Then merge this heap with the original heap. Since each root has at most <math>\log_2 n</math> children, creating this new heap takes time <math>O(\log n)</math>. Merging heaps takes time <math>O(\log n)</math>, so the entire delete minimum operation takes time <math>O(\log n)</math>.<ref name="clrs" /> '''function''' deleteMin(heap) min = heap.trees().first() '''for each''' current '''in''' heap.trees() '''if''' current.root < min.root '''then''' min = current '''for each''' tree '''in''' min.subTrees() tmp.addTree(tree) heap.removeTree(min) merge(heap, tmp) === Decrease key === After '''decreasing''' the key of an element, it may become smaller than the key of its parent, violating the minimum-heap property. If this is the case, exchange the element with its parent, and possibly also with its grandparent, and so on, until the minimum-heap property is no longer violated. Each binomial tree has height at most <math>\log_2 n</math>, so this takes <math>O(\log n)</math> time.<ref name="clrs" /> However, this operation requires that the representation of the tree include pointers from each node to its parent in the tree, somewhat complicating the implementation of other operations.<ref name="brown" /> === Delete === To '''delete''' an element from the heap, decrease its key to negative infinity (or equivalently, to some value lower than any element in the heap) and then delete the minimum in the heap.<ref name="clrs" />
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)