Consider the following example. I am adding random numbers to min heap and at the same time I am adding the same numbers in the same order to the max heap. So at the end those 2 heaps will have the same numbers with difference one being min heap and the second one being max heap.
Now here's the question:
If I decide to remove the maximal element from max heap, will that maximal element from max heap always at the bottom of min heap? If not, then another question is that if i want to remove that max element from min heap with swapping him with the last element of min heap, deleting the last element , would I need to ever run operation which would have to compare that switched element with his child in order to repair min heap? Or will it always be the case to compare it with parent in order to fix min heap?
By definition of a max heap, the root is always larger than it's children. However there is no specific ordering among children so left child isn't always greater than right and vice versa. The max element of max heap, which is the root, will have to be at a leaf in the min heap. We don't know which leaf, this will depend on the configuration of the elements. (ie. the order at which these elements are inserted, because usually elements are inserted to fill from leftmost to rightmost side of the tree)
Related
Is it possible to build a Min Heap only using percolate down ( not using percolate up ) ?
We cannot build a heap using perlocate up method because lets say if we are processing ith element and as part of perlocate up process, we swap the position of ith element with its parent. Now the parent might not satisfy heap property because it can be greater than both children of ith element and thus it will violate the heap property.
How do i get the x-th largest and y-th smallest value of a Priority Queue Heap? I know there are MIN and MAX from the standart STL library but they dont quite do the job for me...
In other words for example i need to get the second smallest value and the third largest value in a Priority Queue Heap that contains lets say 10 variables. I need to compare the variables which I can push in a vector.
i'm doing some college studying in haskell atm, and im stuck at this. The data type is the following:
data Heap a = Empty | Node a (Heap a) (Heap a)
(in this exercise Heap a is always a min-max heap, therefore 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).
The Question:
"randomHeap :: [a] -> IO (Heap a) which generates a random heap, containing all the elements from the argument list.
"Use the function randomRIO :: Random t => (t,t) -> IO t (which is present in System.Random) to calculate a random value within a certain range.
"Note that for a non empty list, the choice of which element to use for the root is unique, what should vary are which elements are used to build the sub-trees."
I'll assume the heap shall be selected uniformly at random from all possibilities. Let's investigate the number f(n) of possibile min-max heaps with n nodes. A uniquely determined node goes at the root, there is no choice in this. We choose a subset of the remaining nodes to go on the left side, then repeat this for both children. f(n+1) = sum_{k=0}^{n}{(n over k) * f(k) * f(n-k)}; f(0) = 0. The first few terms are 1, 1, 2, 6, 24 and 120, which suggests the factorial sequence (and the proof of sequence equality is child's play), which also describes the number of possible orders of our input list. Therefore we can hope that each list order corresponds to a min-max heap.
Having mulled on it for a few minutes, it now seems obvious that after shuffling the list, we can split it at its minimum element, choosing the part of the list on the minimum's left as the mentioned subset, then splitting each half at the maximum element, then splitting each quarter at the minimum element, and so on. Different list orders yield different heaps, so this finite correspondence is one-to-one.
You're probably confused in the definition of heap.
You must chose the root which is the max/min element of the argument, depending on the type of heap. Than use the randomRIO to choose which elements go to each node.
I'm trying to implement a binary heap (priority queue) that has the capabilities of both a min heap and a max heap. It needs to have an insert(value), extractMin(), and an extractMax() method. The extract methods remove the value from the heap and return the value.
I was originally using two arrays, called minHeap and maxHeap, one to store the data in a min heap structure, and the other to store the same data in a max heap structure. So when I call extractMin(), it removes and returns the value from minHeap. Then I have to remove that value from maxHeap as well (and vice-versa if I called extractMax()) in order to keep the data set identical in both heaps. And because of the heap-order property, it's guaranteed that I'll find that value in the leaves of the other heap. Searching for that value in the other heap results in a time complexity of O(n) or more precisely, O(n/2) since I'll only be searching the leaves. Not to mention, the percolatingDown() and percolatingUp() methods to restore the heaps after removing values is already O(log n); so in total, the extract methods would be O(n). The problem is, I need the extract methods to be O(log n).
Is there a better way to go about this?
I also thought of this idea but wanted to know what you all think first.
I just finished coding a "median heap" by placing the smaller half of the data in the max heap and the larger half in the min heap. With that structure, I'm able to easily retrieve the median of a given set of values. And I was thinking of using a similar structure of placing the smaller half of the data in the min heap and the larger half in the max heap and using the mean (rather than the median) of all the values to be the deciding factor of whether to place the value in the max or min heap when calling insert(value). I think this might work as the extract methods would stay O(log n).
The simple way is to just use a binary search tree, as M. Shaw recommends.
If you're required to build this on top of binary heaps, then in each heap, alongside each element, store the element's position in the other heap. Every time you move an element in one heap, you can go straight to its position in the other heap and update it. When you perform a delete-min or delete-max, no expensive linear scan in the other heap is required.
For example, if you store std::pairs with first as the element value and second as the position in the other heap, swapping two elements in the min-heap while updating their counterparts in the max-heap might look like this:
swap(minheap[i], minheap[j]);
maxheap[minheap[i].second].second = i;
maxheap[minheap[j].second].second = j;
You can create a hash table for the heap elements, which is shared by two heaps. The table is indexed by the value of the heap element. The value of the hashed bucket can be a struct consisting of the array index in minHeap and maxHeap respectively.
The benefit of this approach is that it is non-intrusive, meaning that the structure of the heap elements remains the same. And you don't have to create heaps side-by-side. You can create one after the other with the usual heap creation precedure.
E.g.,
struct tIndex
{
// Array index of the element in two heaps respectively
size_t minIndex;
size_t maxIndex;
};
std::unordered_map<int, tIndex> m;
Pay attention that any change to the heap may change the underlying array index of existing elements. So when you add/remove an element, or swap two elements, you may need to update its array index in the hash table accordingly.
You're close. The trick is to use another level of indirection. Keep the keys in an array K[i] and store only indices i in the heaps. Also keep two reverse maps: one for the max heap and one for the min. A reverse map is an array of integers R such that R[i] is the location in the min (or max) heap of the index i for key K[i]. In other words, if M[j] is the min (or max) heap, then R[M[j]] = j; Now whenever you do a sifting operation to move elements around in a heap, you must update the respective reverse map at the same time. In fact it works just like the relation above. At every step where you change a heap element M[j] = z, also update the reverse map R[z] = j; This increases run time by only a small constant factor. Now to delete K[i] from the heap, you can find it in constant time: It's at M[R[i]]. Sift it up to the root and remove it.
I know this works (finding a heap object to delete in constant time) because I've implemented it as part of a bigger algorithm. Check out https://github.com/gene-ressler/lulu/blob/master/ext/lulu/pq.c . The larger algorithm is for map marker merging: https://github.com/gene-ressler/lulu/wiki
http://www.geeksforgeeks.org/a-data-structure-question/
Min-Max heap I would say is the answer as pointed by "user2357112" if the most frequent operation is findMin and findMax. BST might be an overkill if we dont really want a completely ordered data structure , the above is a partial ordered data structured. Refer the link posted above.
http://www.cplusplus.com/reference/algorithm/make_heap/
In this link. it says:
Internally, a heap is a tree where
each node links to values not greater
than its own value. In heaps generated
by make_heap, the specific position of
an element in the tree rather than
being determined by memory-consuming
links is determined by its absolute
position in the sequence, with *first
being always the highest value in the
heap.
about "is determined by its absolute positon in the sequence" .
I confused here.
It also says "a heap is a tree where each node linkes to values not greater than its own value"
Do those 2 sentence contradict? SO confused here.
What exactly tree is for a heap in C++?
Wish any kind person can help me out
Thanks a lot
What this says is that a heap has a typical tree like structure, where each 'parent' node is greater than or equal to the value of the 'child' node ("...where each node links to values not greater than its own value...").
It then goes on to say that instead of using links (i.e. pointers in, say, a struct (like you would use for a linked list)), it uses in-place memory (otherwise known as an array - "...is determined by its absolute position in the sequence...").
*first is the first element (or the largest/smallest, depending on the comparator function) on the heap, and is always at the [0]th index of the array. For each index i, the children are located at [2*i+1] and [2*i+2].
Hope this helps.
If you look at heap implementations you see the tree is implemented as an array. You can find the values below a node at index i at indexes 2 * i+1 and 2 * i +2. So it is a tree, where you can access the elements by their absolute position in the array.