22

In many discussions of binary heap, normally only decrease-key is listed as supported operation for a min-heap. For example, CLR chapter 6.1 and this wikipedia page. Why isn't increase key normally listed for min-heap? I imagine it is possible to do that in O(height) by iteratively swapping the increased element (x) with the minimum of its children, until none of its children is bigger than x.

e.g.

IncreaseKey(int pos, int newValue)
{
   heap[pos] = newValue;
   while(left(pos) < heap.Length)
   {
      int smallest = left(pos);
      if(heap[right(pos)] < heap[left(pos)])
         smallest = right(pos);
      if(heap[pos] < heap[smallest])
      { 
         swap(smallest, pos);
         pos= smallest;
      }
      else return;
   }   
}

Is the above correct? If not, why? If yes, why isn't increase key listed for min-heap?

GatotPujo
  • 221
  • 1
  • 2
  • 3

4 Answers4

8

The reason that your operation is not listed, is that one is not simply interested in all operations that can be easily implemented using a certain data structure, but rather the other way. Given a set of operations, what is the most efficient way (in terms of space and time) to implement these operations. (But I add more to this later)

Binary heaps implement the abstract data structure priority queue, which asks for operations is_empty, add_element (a key with its priority), find_min, and delete_min. More advanced queues also allow one to decrease the priority of the key (in a min_heap) or even increase it. In fact, you have given an implementation.

Two remarks. Your operation is used in the heapify function, that efficiently constructs a heap from an array. In heapify your operation is repeated (starting from the last key).

Then, most importantly, your code uses the position of the node. For the pure data structure priority queue that is cheating. That data structure asks to perform a certain operation given a key. So in order to decrease or increase the priority of an element, you will first have to locate it. I think that is the main reason it is not listed.

Hendrik Jan
  • 31,459
  • 1
  • 54
  • 109
7

The algorithm you suggest is simply heapify. And indeed - if you increase the value of an element in a min-heap, and then heapify its subtree, then you will end up with a legal min-heap.

Shaull
  • 17,814
  • 1
  • 41
  • 67
0

I think that the first thing to consider is what is a supported operation?

Does "inserting a value with a specific, fixed key" (e.g. for keys taken from the integer realm, inserting with key = 3) correspond to a supported operation for the min heap?

No, because that operation can be trivially implemented with more general supported operations. Likewise, inserting 2 elements at once can be done with the exisiting insert operation.

On the other hand, the insert operation cannot be defined otherwise than by exposing implementation details. It is pretty much the same for the operations listed on the wikipedia page, heapify excepted, which could probably be implemented by a sequence of insert.

In other words, there are elementary operations provided on the type, which are tightly bound to the implementation details for them to be performing well, and there are other operations, which do not abide to that rule, and thus may be implemented as a combinations of the canonical ones.

With that definition in mind, do you think that increase-key could be implemented with other supported operations exlusively, without a loss of performance? If so, then it is not a supported operation by the above definition, otherwise, you may well be right.

Arguably, the definition of a supported operation I provide is mine, as far as I know. It is not formal, and thus subject to discussion (although it seems pretty clear to me). However, I would be glad if someone could provide a source which clearly and unambiguously define what a supported operation is for datatypes, or at least define it in better terms than mine (is that definition given in CLR? I don't have a copy).

My second point will be on how we define a priority queue (which is the raison d'ĂȘtre of binary heaps). Is the increase_key a necessary operation for that datatype, i.e. for its proper use?

As you can see my angle is all about definitions. I do not really provide an answer to your questions, merely some pointers, so enhancements are welcome.

didierc
  • 435
  • 2
  • 8
0

The decrease key is in fact mentioned as an exercise 6.5-4 in CLR. Here is why I think it was not presented in the chapter itself: It can be constructed simply by reusing the MAX-HEAPIFY(A, i) i.e. you will only need to compare the element to its children not its parent(since you decreased the key); The comparison to parent is only needed if you increase the key's value and that is a different algorithm ,MAX-HEAP-INCREASE-KEY(A, x, k).

So in short they gave you two algorithm to fix the heap; Algo 1 fixes the heap sub tree by looking at children; Algo 2 fixes the heap subtree by looking at the parent. All the other algorithms can be built using those.

Sid
  • 165
  • 4