Min-max heap

Last updated
Min-max heap
Type binary tree/heap
Invented1986
Time complexity in big O notation
OperationAverageWorst case
InsertO(log n)O(log n)
DeleteO(log n) [1] O(log n)
Space complexity

In computer science, a min-max heap is a complete binary tree data structure which combines the usefulness of both a min-heap and a max-heap, that is, it provides constant time retrieval and logarithmic time removal of both the minimum and maximum elements in it. [2] This makes the min-max heap a very useful data structure to implement a double-ended priority queue. Like binary min-heaps and max-heaps, min-max heaps support logarithmic insertion and deletion and can be built in linear time. [3] Min-max heaps are often represented implicitly in an array; [4] hence it's referred to as an implicit data structure.

Contents

The min-max heap property is: each node at an even level in the tree is less than all of its descendants, while each node at an odd level in the tree is greater than all of its descendants. [4]

The structure can also be generalized to support other order-statistics operations efficiently, such as find-median, delete-median, [2] find(k) (determine the kth smallest value in the structure) and the operation delete(k) (delete the kth smallest value in the structure), for any fixed value (or set of values) of k. These last two operations can be implemented in constant and logarithmic time, respectively. The notion of min-max ordering can be extended to other structures based on the max- or min-ordering, such as leftist trees, generating a new (and more powerful) class of data structures. [4] A min-max heap can also be useful when implementing an external quicksort. [5]

Description

Example of Min-max heap Min-max heap.jpg
Example of Min-max heap

A max-min heap is defined analogously; in such a heap, the maximum value is stored at the root, and the smallest value is stored at one of the root's children. [4]

Operations

In the following operations we assume that the min-max heap is represented in an array A[1..N]; The location in the array will correspond to a node located on the level in the heap.

Build

Creating a min-max heap is accomplished by an adaptation of Floyd's linear-time heap construction algorithm, which proceeds in a bottom-up fashion. [4] A typical Floyd's build-heap algorithm [6] goes as follows:

function FLOYD-BUILD-HEAP(h):     for each index i from down to 1 do:push-down(h, i)     return h

In this function, h is the initial array, whose elements may not be ordered according to the min-max heap property. The push-down operation (which sometimes is also called heapify) of a min-max heap is explained next.

Push Down

The push-down algorithm (or trickle-down as it is called in [4] ) is as follows:

function PUSH-DOWN(h, i):     ifi is on a min level then:PUSH-DOWN-MIN(h, i)     else:PUSH-DOWN-MAX(h, i)     endif

Push Down Min

function PUSH-DOWN-MIN(h, i):     ifi has children then:m := index of the smallest child or grandchild of iifm is a grandchild of ithen:ifh[m] < h[i]then:                 swap h[m] and h[i]ifh[m] > h[parent(m)]then:                     swap h[m] and h[parent(m)]endifPUSH-DOWN(h, m)             endifelse ifh[m] < h[i]then:             swap h[m] and h[i]endifendif

Push Down Max

The algorithm for push-down-max is identical to that for push-down-min, but with all of the comparison operators reversed.

function PUSH-DOWN-MAX(h, i):     ifi has children then:m := index of the largest child or grandchild of iifm is a grandchild of ithen:ifh[m] > h[i]then:                 swap h[m] and h[i]ifh[m] < h[parent(m)]then:                     swap h[m] and h[parent(m)]endifPUSH-DOWN(h, m)             endifelse ifh[m] > h[i]then:             swap h[m] and h[i]endifendif

Iterative Form

As the recursive calls in push-down-min and push-down-max are in tail position, these functions can be trivially converted to purely iterative forms executing in constant space:

function PUSH-DOWN-ITER(h, m):     whilem has children then:i := mifi is on a min level then:m := index of the smallest child or grandchild of iifh[m] < h[i]then:                 swap h[m] and h[i]ifm is a grandchild of ithen:ifh[m] > h[parent(m)]then:                         swap h[m] and h[parent(m)]endifelse                     break                 endifelse                 break              endifelse:m := index of the largest child or grandchild of iifh[m] > h[i]then:                 swap h[m] and h[i]ifm is a grandchild of ithen:ifh[m] < h[parent(m)]then:                         swap h[m] and h[parent(m)]endifelse                     break                 endifelse                 break              endifendifendwhile

Insertion

To add an element to a min-max heap perform following operations:

  1. Append the required key to (the end of) the array representing the min-max heap. This will likely break the min-max heap properties, therefore we need to adjust the heap.
  2. Compare the new key to its parent:
    1. If it is found to be less (greater) than the parent, then it is surely less (greater) than all other nodes on max (min) levels that are on the path to the root of heap. Now, just check for nodes on min (max) levels.
    2. The path from the new node to the root (considering only min (max) levels) should be in a descending (ascending) order as it was before the insertion. So, we need to make a binary insertion of the new node into this sequence. Technically it is simpler to swap the new node with its parent while the parent is greater (less).

This process is implemented by calling the push-up algorithm described below on the index of the newly-appended key.

Push Up

The push-up algorithm (or bubble-up as it is called in [7] ) is as follows:

function PUSH-UP(h, i):     ifi is not the root then:ifi is on a min level then:ifh[i] > h[parent(i)]then:                 swap h[i] and h[parent(i)]PUSH-UP-MAX(h, parent(i))             else:PUSH-UP-MIN(h, i)             endifelse:ifh[i] < h[parent(i)]then:                 swap h[i] and h[parent(i)]PUSH-UP-MIN(h, parent(i))             else:PUSH-UP-MAX(h, i)             endifendifendif

Push Up Min

function PUSH-UP-MIN(h, i):     ifi has a grandparent andh[i] < h[grandparent(i)]then:         swap h[i] and h[grandparent(i)]PUSH-UP-MIN(h, grandparent(i))     endif

Push Up Max

As with the push-down operations, push-up-max is identical to push-up-min, but with comparison operators reversed:

function PUSH-UP-MAX(h, i):     ifi has a grandparent andh[i] > h[grandparent(i)]then:         swap h[i] and h[grandparent(i)]PUSH-UP-MAX(h, grandparent(i))     endif

Iterative Form

As the recursive calls to push-up-min and push-up-max are in tail position, these functions also can be trivially converted to purely iterative forms executing in constant space:

function PUSH-UP-MIN-ITER(h, i):     whilei has a grandparent andh[i] < h[grandparent(i)]then:         swap h[i] and h[grandparent(i)]i := grandparent(i)endwhile

Example

Here is one example for inserting an element to a Min-Max Heap.

Say we have the following min-max heap and want to insert a new node with value 6.

Min-max heap.jpg

Initially, node 6 is inserted as a right child of the node 11. 6 is less than 11, therefore it is less than all the nodes on the max levels (41), and we need to check only the min levels (8 and 11). We should swap the nodes 6 and 11 and then swap 6 and 8. So, 6 gets moved to the root position of the heap, the former root 8 gets moved down to replace 11, and 11 becomes a right child of 8.

Consider adding the new node 81 instead of 6. Initially, the node is inserted as a right child of the node 11. 81 is greater than 11, therefore it is greater than any node on any of the min levels (8 and 11). Now, we only need to check the nodes on the max levels (41) and make one swap.

Find Minimum

The minimum node (or a minimum node in the case of duplicate keys) of a Min-Max Heap is always located at the root. Find Minimum is thus a trivial constant time operation which simply returns the roots.

Find Maximum

The maximum node (or a maximum node in the case of duplicate keys) of a Min-Max Heap that contains more than one node is always located on the first max level--i.e., as one of the immediate children of the root. Find Maximum thus requires at most one comparison, to determine which of the two children of the root is larger, and as such is also a constant time operation. If the Min-Max heap contains one node then that node is the maximum node.

Remove Minimum

Removing the minimum is just a special case of removing an arbitrary node whose index in the array is known. In this case, the last element of the array is removed (reducing the length of the array) and used to replace the root, at the head of the array. push-down is then called on the root index to restore the heap property in time.

Remove Maximum

Removing the maximum is again a special case of removing an arbitrary node with known index. As in the Find Maximum operation, a single comparison is required to identify the maximal child of the root, after which it is replaced with the final element of the array and push-down is then called on the index of the replaced maximum to restore the heap property.

Extensions

The min-max-median heap is a variant of the min-max heap, suggested in the original publication on the structure, that supports the operations of an order statistic tree.

Related Research Articles

<span class="mw-page-title-main">Heapsort</span> A sorting algorithm which uses the heap data structure

In computer science, heapsort is a comparison-based sorting algorithm which can be thought of as "an implementation of selection sort using the right data structure." Like selection sort, heapsort divides its input into a sorted and an unsorted region, and it iteratively shrinks the unsorted region by extracting the largest element from it and inserting it into the sorted region. Unlike selection sort, heapsort does not waste time with a linear-time scan of the unsorted region; rather, heap sort maintains the unsorted region in a heap data structure to efficiently find the largest element in each step.

<span class="mw-page-title-main">Heap (data structure)</span> Computer science data structure

In computer science, a heap is a tree-based data structure that satisfies the heap property: In a max heap, for any given node C, if P is a parent node of C, then the key of P is greater than or equal to the key of C. In a min heap, the key of P is less than or equal to the key of C. The node at the "top" of the heap is called the root node.

In computer science, a priority queue is an abstract data-type similar to a regular queue or stack data structure. Each element in a priority queue has an associated priority. In a priority queue, elements with high priority are served before elements with low priority. In some implementations, if two elements have the same priority, they are served in the same order in which they were enqueued. In other implementations, the order of elements with the same priority is undefined.

In computer science, a red–black tree is a specialised binary search tree data structure noted for fast storage and retrieval of ordered information, and a guarantee that operations will complete within a known time. Compared to other self-balancing binary search trees, the nodes in a red-black tree hold an extra bit called "color" representing "red" and "black" which is used when re-organising the tree to ensure that it is always approximately balanced.

A splay tree is a binary search tree with the additional property that recently accessed elements are quick to access again. Like self-balancing binary search trees, a splay tree performs basic operations such as insertion, look-up and removal in O(log n) amortized time. For random access patterns drawn from a non-uniform random distribution, their amortized time can be faster than logarithmic, proportional to the entropy of the access pattern. For many patterns of non-random operations, also, splay trees can take better than logarithmic time, without requiring advance knowledge of the pattern. According to the unproven dynamic optimality conjecture, their performance on all access patterns is within a constant factor of the best possible performance that could be achieved by any other self-adjusting binary search tree, even one selected to fit that pattern. The splay tree was invented by Daniel Sleator and Robert Tarjan in 1985.

<span class="mw-page-title-main">Binary heap</span> Variant of heap data structure

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 in 1964, as a data structure for heapsort.

<span class="mw-page-title-main">Treap</span> Random search tree data structure

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 insertions and deletions of keys, the shape of the tree is a random variable with the same probability distribution as a random binary tree; in particular, with high probability its height is proportional to the logarithm of the number of keys, so that each search, insertion, or deletion operation takes logarithmic time to perform.

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, which is a priority queue supporting merge operation. It is implemented as a heap similar to a binary heap but using a special tree structure that is different from the complete binary trees used by binary heaps. Binomial heaps were invented in 1978 by Jean Vuillemin.

In computer science, a Fibonacci heap is a data structure for priority queue operations, consisting of a collection of heap-ordered trees. It has a better amortized running time than many other priority queue data structures including the binary heap and binomial heap. Michael L. Fredman and Robert E. Tarjan developed Fibonacci heaps in 1984 and published them in a scientific journal in 1987. Fibonacci heaps are named after the Fibonacci numbers, which are used in their running time analysis.

In computer science, tree traversal is a form of graph traversal and refers to the process of visiting each node in a tree data structure, exactly once. Such traversals are classified by the order in which the nodes are visited. The following algorithms are described for a binary tree, but they may be generalized to other trees as well.

A van Emde Boas tree, also known as a vEB tree or van Emde Boas priority queue, is a tree data structure which implements an associative array with m-bit integer keys. It was invented by a team led by Dutch computer scientist Peter van Emde Boas in 1975. It performs all operations in O(log m) time, or equivalently in O(log log M) time, where M = 2m is the largest element that can be stored in the tree. The parameter M is not to be confused with the actual number of elements stored in the tree, by which the performance of other tree data-structures is often measured.

In computer science, a leftist tree or leftist heap is a priority queue implemented with a variant of a binary heap. Every node x has an s-value which is the distance to the nearest leaf in subtree rooted at x. In contrast to a binary heap, a leftist tree attempts to be very unbalanced. In addition to the heap property, leftist trees are maintained so the right descendant of each node has the lower s-value.

A pairing heap is a type of heap data structure with relatively simple implementation and excellent practical amortized performance, introduced by Michael Fredman, Robert Sedgewick, Daniel Sleator, and Robert Tarjan in 1986. Pairing heaps are heap-ordered multiway tree structures, and can be considered simplified Fibonacci heaps. They are considered a "robust choice" for implementing such algorithms as Prim's MST algorithm, and support the following operations :

In computer science, adaptive heap sort is a comparison-based sorting algorithm of the adaptive sort family. It is a variant of heap sort that performs better when the data contains existing order. Published by Christos Levcopoulos and Ola Petersson in 1992, the algorithm utilizes a new measure of presortedness, Osc, as the number of oscillations. Instead of putting all the data into the heap as the traditional heap sort did, adaptive heap sort only take part of the data into the heap so that the run time will reduce significantly when the presortedness of the data is high.

The d-ary heap or d-heap is a priority queue data structure, a generalization of the binary heap in which the nodes have d children instead of 2. Thus, a binary heap is a 2-heap, and a ternary heap is a 3-heap. According to Tarjan and Jensen et al., d-ary heaps were invented by Donald B. Johnson in 1975.

<span class="mw-page-title-main">Kinetic heap</span>

A Kinetic Heap is a kinetic data structure, obtained by the kinetization of a heap. It is designed to store elements where the priority is changing as a continuous function of time. As a type of kinetic priority queue, it maintains the maximum priority element stored in it. The kinetic heap data structure works by storing the elements as a tree that satisfies the following heap property – if B is a child node of A, then the priority of the element in A must be higher than the priority of the element in B. This heap property is enforced using certificates along every edge so, like other kinetic data structures, a kinetic heap also contains a priority queue to maintain certificate failure times.

In computer science, k-way merge algorithms or multiway merges are a specific type of sequence merge algorithms that specialize in taking in k sorted lists and merging them into a single sorted list. These merge algorithms generally refer to merge algorithms that take in a number of sorted lists greater than two. Two-way merges are also referred to as binary merges.The k- way merge is also an external sorting algorithm.

In computer science, a weak heap is a data structure for priority queues, combining features of the binary heap and binomial heap. It can be stored in an array as an implicit binary tree like a binary heap, and has the efficiency guarantees of binomial heaps.

Interpolation sort is a sorting algorithm that is a kind of bucket sort. It uses an interpolation formula to assign data to the bucket. A general interpolation formula is:

The PH-tree is a tree data structure used for spatial indexing of multi-dimensional data (keys) such as geographical coordinates, points, feature vectors, rectangles or bounding boxes. The PH-tree is space partitioning index with a structure similar to that of a quadtree or octree. However, unlike quadtrees, it uses a splitting policy based on tries and similar to Crit bit trees that is based on the bit-representation of the keys. The bit-based splitting policy, when combined with the use of different internal representations for nodes, provides scalability with high-dimensional data. The bit-representation splitting policy also imposes a maximum depth, thus avoiding degenerated trees and the need for rebalancing.

References

  1. Mischel. "Jim". Stack Overflow. Retrieved 8 September 2016.
  2. 1 2 ATKINSON, M. D; SACK, J.-R; SANTORO, N.; STROTHOTTE, T. (1986). Munro, Ian (ed.). "Min-Max Heaps and Generalized Priority Queues" (PDF). Communications of the ACM. 29 (10): 996–1000. doi:10.1145/6617.6621. S2CID   3090797.
  3. ATKINSON, M. D; SACK, J.-R; SANTORO, N.; STROTHOTTE, T. (1986). Munro, Ian (ed.). "Min-Max Heaps and Generalized Priority Queues" (PDF). Communications of the ACM. 29 (10): 996–1000. doi:10.1145/6617.6621. S2CID   3090797.
  4. 1 2 3 4 5 6 ATKINSON, M. D; SACK, J.-R; SANTORO, N.; STROTHOTTE, T. (1986). Munro, Ian (ed.). "Min-Max Heaps and Generalized Priority Queues" (PDF). Communications of the ACM. 29 (10): 996–1000. doi:10.1145/6617.6621. S2CID   3090797.
  5. Gonnet, Gaston H.; Baeza-Yates, Ricardo (1991). Handbook of Algorithms and Data Structures: In Pascal and C. ISBN   0201416077.
  6. K. Paparrizos, Ioannis (2011). "A tight bound on the worst-case number of comparisons for Floyd's heap construction algorithm". arXiv: 1012.0956 . Bibcode:2010arXiv1012.0956P.{{cite journal}}: Cite journal requires |journal= (help)
  7. ATKINSON, M. D; SACK, J.-R; SANTORO, N.; STROTHOTTE, T. (1986). Munro, Ian (ed.). "Min-Max Heaps and Generalized Priority Queues" (PDF). Communications of the ACM. 29 (10): 996–1000. doi:10.1145/6617.6621. S2CID   3090797.