Binary heap
   HOME

TheInfoList



OR:

A binary heap is a heap data structure that takes the form of a binary tree. Binary heaps are a common way of implementing priority queues. The binary heap was introduced by
J. W. J. Williams John William Joseph Williams (2 September 1930 – 29 September 2012) was a Welsh-Canadian computer scientist best known for inventing in 1964 heapsort and the binary heap data structure. He was born in Chippenham, Wiltshire''England & Wales, Civ ...
in 1964, as a data structure for
heapsort In computer science, heapsort is a comparison-based sorting algorithm. Heapsort can be thought of as an improved selection sort: like selection sort, heapsort divides its input into a sorted and an unsorted region, and it iteratively shrinks the ...
. A binary heap is defined as a binary tree with two additional constraints: *Shape property: a binary heap is a ''
complete binary tree In computer science, a binary tree is a k-ary k = 2 tree data structure in which each node has at most two children, which are referred to as the ' and the '. A recursive definition using just set theory notions is that a (non-empty) binary tr ...
''; that is, all levels of the tree, except possibly the last one (deepest) are fully filled, and, if the last level of the tree is not complete, the nodes of that level are filled from left to right. *Heap property: the key stored in each node is either greater than or equal to (≥) or less than or equal to (≤) the keys in the node's children, according to some
total order In mathematics, a total or linear order is a partial order in which any two elements are comparable. That is, a total order is a binary relation \leq on some set X, which satisfies the following for all a, b and c in X: # a \leq a ( reflex ...
. Heaps where the parent key is greater than or equal to (≥) the child keys are called ''max-heaps''; those where it is less than or equal to (≤) are called ''min-heaps''. Efficient (
logarithmic time In computer science, the time complexity is the computational complexity that describes the amount of computer time it takes to run an algorithm. Time complexity is commonly estimated by counting the number of elementary operations performed by t ...
) algorithms are known for the two operations needed to implement a priority queue on a binary heap: inserting an element, and removing the smallest or largest element from a min-heap or max-heap, respectively. Binary heaps are also commonly employed in the
heapsort In computer science, heapsort is a comparison-based sorting algorithm. Heapsort can be thought of as an improved selection sort: like selection sort, heapsort divides its input into a sorted and an unsorted region, and it iteratively shrinks the ...
sorting algorithm In computer science, a sorting algorithm is an algorithm that puts elements of a list into an order. The most frequently used orders are numerical order and lexicographical order, and either ascending or descending. Efficient sorting is important ...
, which is an in-place algorithm because binary heaps can be implemented as an
implicit data structure In computer science, an implicit data structure or space-efficient data structure is a data structure that stores very little information other than the main or required data: a data structure that requires low overhead. They are called "implicit" ...
, storing keys in an array and using their relative positions within that array to represent child–parent relationships.


Heap operations

Both the insert and remove operations modify the heap to conform to the shape property first, by adding or removing from the end of the heap. Then the heap property is restored by traversing up or down the heap. Both operations take time.


Insert

To add an element to a heap, we can perform this algorithm: #Add the element to the bottom level of the heap at the leftmost open space. #Compare the added element with its parent; if they are in the correct order, stop. #If not, swap the element with its parent and return to the previous step. Steps 2 and 3, which restore the heap property by comparing and possibly swapping a node with its parent, are called ''the up-heap'' operation (also known as ''bubble-up'', ''percolate-up'', ''sift-up'', ''trickle-up'', ''swim-up'', ''heapify-up'', or ''cascade-up''). The number of operations required depends only on the number of levels the new element must rise to satisfy the heap property. Thus, the insertion operation has a worst-case time complexity of . For a random heap, and for repeated insertions, the insertion operation has an average-case complexity of O(1). As an example of binary heap insertion, say we have a max-heap :: and we want to add the number 15 to the heap. We first place the 15 in the position marked by the X. However, the heap property is violated since , so we need to swap the 15 and the 8. So, we have the heap looking as follows after the first swap: :: However the heap property is still violated since , so we need to swap again: :: which is a valid max-heap. There is no need to check the left child after this final step: at the start, the max-heap was valid, meaning the root was already greater than its left child, so replacing the root with an even greater value will maintain the property that each node is greater than its children (; if , and , then , because of the
transitive relation In mathematics, a relation on a set is transitive if, for all elements , , in , whenever relates to and to , then also relates to . Each partial order as well as each equivalence relation needs to be transitive. Definition A ho ...
).


Extract

The procedure for deleting the root from the heap (effectively extracting the maximum element in a max-heap or the minimum element in a min-heap) while retaining the heap property is as follows: #Replace the root of the heap with the last element on the last level. #Compare the new root with its children; if they are in the correct order, stop. #If not, swap the element with one of its children and return to the previous step. (Swap with its smaller child in a min-heap and its larger child in a max-heap.) Steps 2 and 3, which restore the heap property by comparing and possibly swapping a node with one of its children, are called the ''down-heap'' (also known as ''bubble-down'', ''percolate-down'', ''sift-down'', ''sink-down'', ''trickle down'', ''heapify-down'', ''cascade-down'', ''extract-min'' or ''extract-max'', or simply ''heapify'') operation. So, if we have the same max-heap as before :: We remove the 11 and replace it with the 4. :: Now the heap property is violated since 8 is greater than 4. In this case, swapping the two elements, 4 and 8, is enough to restore the heap property and we need not swap elements further: :: The downward-moving node is swapped with the ''larger'' of its children in a max-heap (in a min-heap it would be swapped with its smaller child), until it satisfies the heap property in its new position. This functionality is achieved by the Max-Heapify function as defined below in pseudocode for an
array An array is a systematic arrangement of similar objects, usually in rows and columns. Things called an array include: {{TOC right Music * In twelve-tone and serial composition, the presentation of simultaneous twelve-tone sets such that the ...
-backed heap ''A'' of length ''length''(''A''). ''A'' is indexed starting at 1. // Perform a down-heap or heapify-down operation for a max-heap // ''A'': an array representing the heap, indexed starting at 1 // ''i'': the index to start at when heapifying down Max-Heapify(''A'', ''i''): ''left'' ← 2×''i'' ''right'' ← 2×''i'' + 1 ''largest'' ← ''i'' if ''left'' ≤ ''length''(''A'') and ''A'' 'left''> A 'largest''then: ''largest'' ← ''left''
if ''right'' ≤ ''length''(''A'') and ''A'' 'right''> ''A'' 'largest''then: ''largest'' ← ''right'' if ''largest'' ≠ ''i'' then: swap ''A'' 'i''and ''A'' 'largest'' Max-Heapify(''A'', ''largest'') For the above algorithm to correctly re-heapify the array, no nodes besides the node at index ''i'' and its two direct children can violate the heap property. The down-heap operation (without the preceding swap) can also be used to modify the value of the root, even when an element is not being deleted. In the worst case, the new root has to be swapped with its child on each level until it reaches the bottom level of the heap, meaning that the delete operation has a time complexity relative to the height of the tree, or O(log ''n'').


Insert then extract

Inserting an element then extracting from the heap can be done more efficiently than simply calling the insert and extract functions defined above, which would involve both an upheap and downheap operation. Instead, we can do just a downheap operation, as follows: # Compare whether the item we're pushing or the peeked top of the heap is greater (assuming a max heap) # If the root of the heap is greater: ## Replace the root with the new item ## Down-heapify starting from the root # Else, return the item we're pushing
Python Python may refer to: Snakes * Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia ** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia * Python (mythology), a mythical serpent Computing * Python (pro ...
provides such a function for insertion then extraction called "heappushpop", which is paraphrased below. The heap array is assumed to have its first element at index 1. // Push a new item to a (max) heap and then extract the root of the resulting heap. // ''heap'': an array representing the heap, indexed at 1 // ''item'': an element to insert // Returns the greater of the two between ''item'' and the root of ''heap''. Push-Pop(''heap'': List, ''item'': T) -> T: if ''heap'' is not empty and heap > ''item'' then: // < if min heap swap ''heap'' and ''item'' _downheap(''heap'' starting from index 1) return ''item'' A similar function can be defined for popping and then inserting, which in Python is called "heapreplace": // Extract the root of the heap, and push a new item // ''heap'': an array representing the heap, indexed at 1 // ''item'': an element to insert // Returns the current root of ''heap'' Replace(''heap'': List, ''item'': T) -> T: swap ''heap'' and ''item'' _downheap(''heap'' starting from index 1) return ''item''


Search

Finding an arbitrary element takes O(n) time.


Delete

Deleting an arbitrary element can be done as follows: # Find the index i of the element we want to delete # Swap this element with the last element # Down-heapify or up-heapify to restore the heap property. In a max-heap (min-heap), up-heapify is only required when the new key of element i is greater (smaller) than the previous one because only the heap-property of the parent element might be violated. Assuming that the heap-property was valid between element i and its children before the element swap, it can't be violated by a now larger (smaller) key value. When the new key is less (greater) than the previous one then only a down-heapify is required because the heap-property might only be violated in the child elements.


Decrease or increase key

The decrease key operation replaces the value of a node with a given value with a lower value, and the increase key operation does the same but with a higher value. This involves finding the node with the given value, changing the value, and then down-heapifying or up-heapifying to restore the heap property. Decrease key can be done as follows: # Find the index of the element we want to modify # Decrease the value of the node # Down-heapify (assuming a max heap) to restore the heap property Increase key can be done as follows: # Find the index of the element we want to modify # Increase the value of the node # Up-heapify (assuming a max heap) to restore the heap property


Building a heap

Building a heap from an array of input elements can be done by starting with an empty heap, then successively inserting each element. This approach, called Williams' method after the inventor of binary heaps, is easily seen to run in time: it performs insertions at cost each. However, Williams' method is suboptimal. A faster method (due to Floyd) starts by arbitrarily putting the elements on a binary tree, respecting the shape property (the tree could be represented by an array, see below). Then starting from the lowest level and moving upwards, sift the root of each subtree downward as in the deletion algorithm until the heap property is restored. More specifically if all the subtrees starting at some height h have already been "heapified" (the bottommost level corresponding to h=0), the trees at height h+1 can be heapified by sending their root down along the path of maximum valued children when building a max-heap, or minimum valued children when building a min-heap. This process takes O(h) operations (swaps) per node. In this method most of the heapification takes place in the lower levels. Since the height of the heap is \lfloor \log n \rfloor, the number of nodes at height h is \le \frac \le \frac. Therefore, the cost of heapifying all subtrees is: : \begin \sum_^ \frac O(h) & = O\left(n\sum_^ \frac\right) \\ & = O\left(n\sum_^ \frac\right) \\ & = O(n) \end This uses the fact that the given infinite
series Series may refer to: People with the name * Caroline Series (born 1951), English mathematician, daughter of George Series * George Series (1920–1995), English physicist Arts, entertainment, and media Music * Series, the ordered sets used in ...
\sum_^\infty i/2^i converges. The exact value of the above (the worst-case number of comparisons during the heap construction) is known to be equal to: : 2 n - 2 s_2 (n) - e_2 (n) , where is the sum of all digits of the binary representation of and is the exponent of in the prime factorization of . The average case is more complex to analyze, but it can be shown to asymptotically approach comparisons. The Build-Max-Heap function that follows, converts an array ''A'' which stores a complete binary tree with ''n'' nodes to a max-heap by repeatedly using Max-Heapify (down-heapify for a max-heap) in a bottom-up manner. The array elements indexed by , , ..., ''n'' are all leaves for the tree (assuming that indices start at 1)—thus each is a one-element heap, and does not need to be down-heapified. Build-Max-Heap runs Max-Heapify on each of the remaining tree nodes. Build-Max-Heap (''A''): for each index ''i'' from ''floor''(''length''(''A'')/2) downto 1 do: Max-Heapify(''A'', ''i'')


Heap implementation

Heaps are commonly implemented with an
array An array is a systematic arrangement of similar objects, usually in rows and columns. Things called an array include: {{TOC right Music * In twelve-tone and serial composition, the presentation of simultaneous twelve-tone sets such that the ...
. Any binary tree can be stored in an array, but because a binary heap is always a complete binary tree, it can be stored compactly. No space is required for pointers; instead, the parent and children of each node can be found by arithmetic on array indices. These properties make this heap implementation a simple example of an
implicit data structure In computer science, an implicit data structure or space-efficient data structure is a data structure that stores very little information other than the main or required data: a data structure that requires low overhead. They are called "implicit" ...
or
Ahnentafel An ''ahnentafel'' (German for "ancestor table"; ) or ''ahnenreihe'' ("ancestor series"; ) is a genealogical numbering system for listing a person's direct ancestors in a fixed sequence of ascent. The subject (or proband) of the ahnentafel is l ...
list. Details depend on the root position, which in turn may depend on constraints of a
programming language A programming language is a system of notation for writing computer programs. Most programming languages are text-based formal languages, but they may also be graphical. They are a kind of computer language. The description of a programming ...
used for implementation, or programmer preference. Specifically, sometimes the root is placed at index 1, in order to simplify arithmetic. Let ''n'' be the number of elements in the heap and ''i'' be an arbitrary valid index of the array storing the heap. If the tree root is at index 0, with valid indices 0 through ''n − ''1, then each element ''a'' at index ''i'' has * children at indices 2''i ''+ 1 and 2''i ''+ 2 * its parent at index '' floor''((''i'' − 1) / 2). Alternatively, if the tree root is at index 1, with valid indices 1 through ''n'', then each element ''a'' at index ''i'' has * children at indices 2''i'' and 2''i ''+1 * its parent at index '' floor''(''i'' / 2). This implementation is used in the
heapsort In computer science, heapsort is a comparison-based sorting algorithm. Heapsort can be thought of as an improved selection sort: like selection sort, heapsort divides its input into a sorted and an unsorted region, and it iteratively shrinks the ...
algorithm which reuses the space allocated to the input array to store the heap (i.e. the algorithm is done
in-place In computer science, an in-place algorithm is an algorithm which transforms input using no auxiliary data structure. However, a small amount of extra storage space is allowed for auxiliary variables. The input is usually overwritten by the output ...
). This implementation is also useful as a Priority queue. When a dynamic array is used, insertion of an unbounded number of items is possible. The upheap/downheap operations can then be stated in terms of an array as follows: suppose that the heap property holds for the indices ''b'', ''b''+1, ..., ''e''. The sift-down function extends the heap property to ''b''−1, ''b'', ''b''+1, ..., ''e''. Only index ''i'' = ''b''−1 can violate the heap property. Let ''j'' be the index of the largest child of ''a'' 'i''(for a max-heap, or the smallest child for a min-heap) within the range ''b'', ..., ''e''. (If no such index exists because then the heap property holds for the newly extended range and nothing needs to be done.) By swapping the values ''a'' 'i''and ''a'' 'j''the heap property for position ''i'' is established. At this point, the only problem is that the heap property might not hold for index ''j''. The sift-down function is applied tail-recursively to index ''j'' until the heap property is established for all elements. The sift-down function is fast. In each step it only needs two comparisons and one swap. The index value where it is working doubles in each iteration, so that at most log2 ''e'' steps are required. For big heaps and using
virtual memory In computing, virtual memory, or virtual storage is a memory management technique that provides an "idealized abstraction of the storage resources that are actually available on a given machine" which "creates the illusion to users of a very ...
, storing elements in an array according to the above scheme is inefficient: (almost) every level is in a different
page Page most commonly refers to: * Page (paper), one side of a leaf of paper, as in a book Page, PAGE, pages, or paging may also refer to: Roles * Page (assistance occupation), a professional occupation * Page (servant), traditionally a young m ...
. B-heaps are binary heaps that keep subtrees in a single page, reducing the number of pages accessed by up to a factor of ten. The operation of merging two binary heaps takes Θ(''n'') for equal-sized heaps. The best you can do is (in case of array implementation) simply concatenating the two heap arrays and build a heap of the result. A heap on ''n'' elements can be merged with a heap on ''k'' elements using O(log ''n'' log ''k'') key comparisons, or, in case of a pointer-based implementation, in O(log ''n'' log ''k'') time. An algorithm for splitting a heap on ''n'' elements into two heaps on ''k'' and ''n-k'' elements, respectively, based on a new view of heaps as an ordered collections of subheaps was presented in. The algorithm requires O(log ''n'' * log ''n'') comparisons. The view also presents a new and conceptually simple algorithm for merging heaps. When merging is a common task, a different heap implementation is recommended, such as
binomial heap In computer science, a binomial heap is a data structure that acts as a priority queue but also allows pairs of heaps to be merged. It is important as an implementation of the mergeable heap abstract data type (also called meldable heap), whi ...
s, which can be merged in O(log ''n''). Additionally, a binary heap can be implemented with a traditional binary tree data structure, but there is an issue with finding the adjacent element on the last level on the binary heap when adding an element. This element can be determined algorithmically or by adding extra data to the nodes, called "threading" the tree—instead of merely storing references to the children, we store the inorder successor of the node as well. It is possible to modify the heap structure to make the extraction of both the smallest and largest element possible in O(\log n) time. To do this, the rows alternate between min heap and max-heap. The algorithms are roughly the same, but, in each step, one must consider the alternating rows with alternating comparisons. The performance is roughly the same as a normal single direction heap. This idea can be generalized to a min-max-median heap.


Derivation of index equations

In an array-based heap, the children and parent of a node can be located via simple arithmetic on the node's index. This section derives the relevant equations for heaps with their root at index 0, with additional notes on heaps with their root at index 1. To avoid confusion, we'll define the level of a node as its distance from the root, such that the root itself occupies level 0.


Child nodes

For a general node located at index (beginning from 0), we will first derive the index of its right child, \text = 2i + 2. Let node be located in level , and note that any level contains exactly 2^l nodes. Furthermore, there are exactly 2^ - 1 nodes contained in the layers up to and including layer (think of binary arithmetic; 0111...111 = 1000...000 - 1). Because the root is stored at 0, the th node will be stored at index (k - 1). Putting these observations together yields the following expression for the index of the last node in layer . ::\text(l) = (2^ - 1) - 1 = 2^ - 2 Let there be nodes after node in layer L, such that ::\begin i = & \quad \text(L) - j\\ = & \quad (2^ -2) - j\\ \end Each of these nodes must have exactly 2 children, so there must be 2j nodes separating 's right child from the end of its layer (L + 1). ::\begin \text = & \quad \text -2j\\ = & \quad (2^ -2) -2j\\ = & \quad 2(2^ -2 -j) + 2\\ = & \quad 2i + 2 \end As required. Noting that the left child of any node is always 1 place before its right child, we get \text = 2i + 1. If the root is located at index 1 instead of 0, the last node in each level is instead at index 2^ - 1. Using this throughout yields \text = 2i and \text = 2i + 1 for heaps with their root at 1.


Parent node

Every node is either the left or right child of its parent, so we know that either of the following is true. # i = 2 \times (\text) + 1 # i = 2 \times (\text) + 2 Hence, ::\text = \frac \;\textrm\; \frac Now consider the expression \left\lfloor \dfrac \right\rfloor. If node i is a left child, this gives the result immediately, however, it also gives the correct result if node i is a right child. In this case, (i - 2) must be even, and hence (i - 1) must be odd. ::\begin \left\lfloor \dfrac \right\rfloor = & \quad \left\lfloor \dfrac + \dfrac \right\rfloor\\ = & \quad \frac\\ = & \quad \text \end Therefore, irrespective of whether a node is a left or right child, its parent can be found by the expression: ::\text = \left\lfloor \dfrac \right\rfloor


Related structures

Since the ordering of siblings in a heap is not specified by the heap property, a single node's two children can be freely interchanged unless doing so violates the shape property (compare with
treap In computer science, the treap and the randomized binary search tree are two closely related forms of binary search tree data structures that maintain a dynamic set of ordered keys and allow binary searches among the keys. After any sequence of in ...
). Note, however, that in the common array-based heap, simply swapping the children might also necessitate moving the children's sub-tree nodes to retain the heap property. The binary heap is a special case of the d-ary heap in which d = 2.


Summary of running times


See also

* Heap *
Heapsort In computer science, heapsort is a comparison-based sorting algorithm. Heapsort can be thought of as an improved selection sort: like selection sort, heapsort divides its input into a sorted and an unsorted region, and it iteratively shrinks the ...


References


External links


Open Data Structures - Section 10.1 - BinaryHeap: An Implicit Binary Tree
Pat Morin Patrick Ryan Morin is a Canadian computer scientist specializing in computational geometry and data structures. He is a professor in the School of Computer Science at Carleton University. Education and career Morin was educated at Carleton Univers ...

Implementation of binary max heap in C
by Robin Thomas
Implementation of binary min heap in C
by Robin Thomas {{DEFAULTSORT:Binary Heap Heaps (data structures) Binary trees