Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print a tree in sorted order using heap properties (Cormen)

I am refreshing on algorithm theory (from Cormen).
There is an exercise in the chapter for binary tries that asks:

Can the min-heap property be used to print out the keys of an n-node tree in sorted order in O(n) time? Show how, or explain why not.

I thought yes it is possible.
In the min heap the element in a node is smaller than both its children.
So the root of the heap is always the smaller element of all the n elements and the left child of the root is the smaller than all the elements in the left subtree and the right child of the root is the smaller than all the elements in the right subtree etc.

So if keep we exracting the root, print it and then update the root with the smaller of its children we keep the min-heap property and we print in sorted order. (I am thinking of a min heap that is not array based).

So this could be done in O(n) time since to update the root, we just compare the 2 children and update the root's pointer to be the smaller of the 2.

But I checked here in the solution:
Cormen Supplement Solutions

And 1)it talks about max-heaps 2) it says it can not be done in O(n) time:

In a heap, a node’s key is both of its children’s keys. In a binary search tree, a node’s key is its left child’s key, but its right child’s key. The heap property, unlike the binary-searth-tree property, doesn’t help print the nodes in sorted order because it doesn’t tell which subtree of a node contains the element to print before that node. In a heap, the largest element smaller than the node could be in either subtree. Note that if the heap property could be used to print the keys in sorted order in O(n) time, we would have an O(n)-time algorithm for sorting, because building the heap takes only O(n) time. But we know (Chapter 8) that a comparison sort must take (n lg n) time.

From my point of view I can understand that using a max-heap, it is not possible to print them in O(n).
But isn't it possible to do it using the min-heap property for the reasoning I explained?
Also why does the solution ignore the min-heap. Is it a typo or error?

Am I misundertanding something here?

like image 514
Cratylus Avatar asked Nov 13 '11 10:11

Cratylus


2 Answers

Firstly the omission of min-heaps in the discussion probably isn't a typo, it doesn't really matter if we're talking about a min heap or a max heap (the comparator is just reversed).

The problem with only extracting the root and then replacing with the smaller of its two children is that the left child is not guaranteed to be smaller than all the nodes in the right subtree (and vice verse). Consider the following heap

        1
       / \
      4   6
     /\   /\
    5  8 9  7

After printing 1 you have to reheapify which is to say you extract 1 and replace it with the last element in the last row, in this case 7. You then switch for as long as you need to return the heap to it's correct state

take away root and last node to root
        7
       / \
      4   6
     /\   /
    5  8 9

swap
        4
       / \
      7   6
     /\   /
    5  8 9

swap
        4
       / \
      5   6
     /\   /
    7  8 9

all of that swapping costs you log n time.

If you instead replaced the root node with 4, you would still have to go through the left branch to reheapify the structure adding cost to the linear cost of extracting the root nodes. What if the heap looked like this

        1
       / \
      4   9
     /\   /\
    5  6 11 15
   /\
  8  7

The pages I looked at forming the solution

1) Wikipedia: binary heap

2) Wolfram MathWorld: heap The heaps here are especially helpful in understanding why it's not a linear operation.

like image 109
Matti Lyra Avatar answered Sep 28 '22 00:09

Matti Lyra


Consider an array representation of the min-heap. You have the minimum at the root. Extract the root and replace it with the last array element, i.e. with the last leaf in the lowest, incomplete "row" of leaves. Perform the MIN-HEAPIFY operation (obv. same as CLRS MAX-HEAPIFY, but with reversed comparison). This takes O(log n) and result is the second least element at the root. Repeat until the heap is empty. This gives a sorted sequence.

The complexity of the algorithm is therefore

log (n) + log (n-1) + log (n-2) + ... + 1 <= n*log n

i.e. O(n*log n)

which is to be expected or otherwise, we would have obtained a comparison based sort with complexity less than O(nlogn) and this is impossible.

like image 40
chill Avatar answered Sep 28 '22 01:09

chill