2

Below is the Pseudo Code of HEAPSORT on an array

HEAPSORT(A)
  BUILD-MAX-HEAP(A)
  for i = A.length downto 2
     exchange A[1] with A[i]
     A.heapsize = A.heapsize - 1
     MAX-HEAPIFY(A,1)

It is clear to me that BUILD-MAX-HEAP has a complexity of O(n) and MAX-HEAPIFY has a complexity of O(h) where h is the height of the heap which has a max value of logn.

What I don't understand completely is why does HeapSort have a complexity of nlogn. I understand we have n iterations with each a MAX-HEAPIFY. But he MAX-HEAPIFY call gets a HEAP of diminishing size in each iteration. How can then each iteration have a complexity of O(lgn)? Is it tightly bound? Any where I can see the mathematical proof of the same?

lalatnayak
  • 160
  • 1
  • 6
  • 21
  • Related: http://stackoverflow.com/questions/39691923/build-max-heap-running-time-for-array-sorted-in-decreasing-order – A. Sarid Oct 04 '16 at 15:49

2 Answers2

3

Big O notation notates an upper bound. As you've said:

MAX-HEAPIFY has a complexity of O(h) where h is the height of the heap which has a max value of log n.

We don't care if the heap gets smaller. We know that at worst, the heap has height log n. We do this n times, hence n log n.

orlp
  • 112,504
  • 36
  • 218
  • 315
  • Below is the Pseudo Code for BUILD-MAX-HEAP _BUILD-MAX-HEAP(A) A.heapsize = A.length for i = A.length/2 downto 1 MAX-HEAPIFY(A,i) In the above we do take into account the depth of the Heap to calculate the complexity which is O(n). Why would we not do in HEAPSORT? – lalatnayak Oct 04 '16 at 16:03
  • @lalatnayak Because we've cheated and already know that we can do no better than O(n log n) for heapsort (hint: we need a lower bound). Because of that we do not try to improve our upper bound. – orlp Oct 04 '16 at 16:06
  • Thanks, I doubt if I could have figured it out without the hint :) – lalatnayak Oct 04 '16 at 16:15
3

Observe that

log 1 + log 2 + log 3 + ... + log n
= log (1 * 2 * 3 * ... * n)
= log n!

Now, by Stirling's approximation,

n! ≈ sqrt(2πn) * (n/e)n

So:

log n! ≈ n * (log n/e) = n * (log n - 1)  = n log n - n

which is O(n log n) because the n log n term dominates the n term (and the O(log n) term I left out because it is too hard to type withou MathJax).

rici
  • 234,347
  • 28
  • 237
  • 341