简体   繁体   中英

Priority Queue - Binary Heap

I'm trying to implement a priority queue as an sorted array backed minimum binary heap. I'm trying to get the update_key function to run in logarithmic time, but to do this I have to know the position of the item in the array. Is there anyway to do this without the use of a map? If so, how? Thank you

If you really want to be able to change the key of an arbitrary element, a heap is not the best choice of data structure. What it gives you is the combination of:

  1. compact representation (no pointers, just an array and an implicit indexing scheme)
  2. logarithmic insertion, rebalancing
  3. logarithmic removal of the smallest (largest) element.
  4. O(1) access to the value of the smallest (largest) element. -

A side benefit of 1. is that the lack of pointers means you do substantially fewer calls to malloc/free ( new/delete ). A map (represented in the standard library as a balanced binary tree) gives you the middle two of these, adding in

  1. logarithmic find() on any key.

So while you could attach another data structure to your heap, storing pointers in the heap and then making the comparison operator dereference through the pointer, you'd pretty soon find yourself with the complexity in time and space of just using a map in the first place.

Your find key function should operate in log(n) time. Your updating (changing the key) should be constant time. Your remove function should run in log(n) time. Your insert function should be log(n) time.

If these assumptions are true try this: 1) Find your item in your heap (IE: binary search, since it is a sorted array). 2) Update your key (you're just changing a value, constant time) 3) Remove the item from the heap log(n) to reheapify.
4) Insert your item into the heap log(n).

So, you'd have log(n) + 1 + log(n) + log(n) which reduces to log(n).

Note: this is amortized, because if you have to realloc your array, etc... that adds overhead. But you shouldn't do that very often anyway.

That's the tradeoff of the array-backed heap: you get excellent memory use (good locality and minimal overhead), but you lose track of the elements. To solve it, you have to add back some overhead.

One solution would be this. The heap contains objects of type C* . C is a class with an int member heap_index , which is the index of the object in the heap array. Whenever you move an element inside the heap array, you'll have to update its heap_index to set it to the new index.

Update_key (as well as removal of an arbitrary element) is then log(n) time because it takes constant time to find the element (via heap_index ), and log(n) time to bubble it into the correct position.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM