Is it possible to build a Min Heap only using percolate down? - heap

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.

Related

Max and Min heap with the same elements

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)

Is it possible to implement a binary heap that is both a max and a min heap?

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.

Overwrite elements at end of priority queue once specified capacity is met?

I'm trying to search for the nearest N points in a quad tree and using an STL priority queue to store the points as they are found (sorted by distance from the query point).
Points exceeding a max distance from the query point are never added to the queue. However, I also would like to cut off the number of items that can be returned by the search. Currently, I add all points which are closer to the query point than the max distance, and then only read the top N points from the queue.
In testing, this is too slow -- simply adding every point closer than the max distance ends up slowing down as more points are added. I would instead like to only add more points to the queue if either: there are fewer than N points currently in the queue, or the point in question is closer to the query point than the Nth point in the queue, in which case that point is overriden, and does not increase the number of elements in the queue.
Is there a way to do this with the STL priority queue, or is my only option to write my own?
Do you have to know the current N best points while you iterate through them? If not, perhaps you can add all the points to a random-access container (e.g. std::vector)and just call std::partial_sort at the end to get the N best.
If you really need to do it with a priority queue, std::priority_queue won't suffice. You could put something together with the std::algorithm heap functions, which lets you access the underlying container.

Determining the best ADT for a priority queue with changeable elements (C++)

First post here and I'm a beginner - hope I'm making myself useful...
I'm trying to find and understand the ADT/concept that does the job I'm after. I'm guessing it's already out there.
I have an array/list/tree (container to be decided) of objects each of which has a count associated with how much it hasn't been used over iterations of a process. As iterations proceed the count for each object accumulates by 1. The idea is that sooner or later I'm going to need the memory that any unused objects are using so I'll delete them to make space for an object not in RAM (which will have an initial count of '0') - But, if it turns out that I use an object that is still in memory it's count is reset to '0', and I pat myself on the back for not having had to access the disk for its contents.
A cache?
The main process loop would have something similar to the following in it:
if (object needs to be added && (totalNumberOfObjects > someConstant))
object with highest count deleted from RAM and the (heap??)
newObject added with a count of '0'
if (an object already in RAM is accessed by the process)
accessedObject count is set to '0'
for (All objects in RAM)
count++
I could bash about for a (long and buggy time) and build my own mess, but I thought it'd be interesting to learn the most efficient way from word go.
Something like a heap?
You could use a heap for this, but I think it would be overkill. It sounds like you're not going to have a lot of different values for the counts, and you'll have a lot of objects with each count. If that's true, then you only need thread the objects onto a list of objects with the same count. These lists are themselves arranged in a dequeue (or 'deque' as C++ insists on calling it).
The key here is that you need to increment the count of all objects, and presumably you want that to be O(1) if possible, rather than O(N). And it is possible: the key is that each list's header contains also the difference of its count from the next smaller count. The header of the list with the smallest count contains a delta from 0, which is the smallest count. To increment the count of all objects, you only have to increase this single number by one.
To set an object's count to 0, you remove the object from its list (which means you always need to refer to objects by their list iterator, or you need to implement your own intrusive linked list), and either (1) add it to the bottom list, if that list has a count of 0, or (2) create a new bottom list with a count of 0 containing only that object.
The procedure for creating a new object is the same, except that you don't have to unlink it from its current list.
To evict an object from memory, you choose the object at the head of the top list (which is the list with the largest count). If that list becomes empty, you pop it off the dequeue. If you need more memory, you can repeat this operation.
So all operations, including "increment all counts", are O(1). Unfortunately, the storage overhead is two pointers per object, plus two pointers and an integer per unique count (at worst, this is the same as the number of objects, but presumably in practice it's much less). Since it's hard to imagine any other algorithm which uses less than one pointer plus a count for each object, this is probably not even a space-time tradeoff; the additional space requirements are minimal.

about make_heap algorithm in C++

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.