tags:

views:

402

answers:

6

A heap is a list where the following applies:

l[i] <= l[2*i] && l[i] <= [2*i+1]

for 0 <= i < len(list)

I'm looking for in-place sorting.

A: 

Read the items off the top of the heap one by one. Basically what you have then is heap sort.

Antti Rasinen
This works, but not in-place.
ΤΖΩΤΖΙΟΥ
+1  A: 

Well you are half way through a Heap Sort already, by having your data in a heap. You just need to implement the second part of the heap sort algorithm. This should be faster than using quicksort on the heap array.

If you are feeling brave you could have a go at implementing smoothsort, which is faster than heapsort for nearly-sorted data.

Matt Howells
Thanks for the smoothsort suggestion.
ΤΖΩΤΖΙΟΥ
A: 

Sorting a heap in-place kind of sounds like a job for Heap Sort.

I assume memory is constrained, an embedded app, perhaps?

Mike Woodhouse
Yes, it's in a memory-constrained environment.
ΤΖΩΤΖΙΟΥ
+2  A: 

Just use heap-sort. It is in-place. That would be the most natural choice.

You can as well just use your heap as it and sort it with some other algorithm. Afterwards you re-build your heap from the sorted list. Quicksort is a good candidate because you can be sure it won't run in the worst-case O(n²) order simply because your heap is already pre-sorted.

That may be faster if your compare-function is expensive. Heap-sort tend to evaluate the compare-function quite often.

Nils Pipenbrinck
quicksort is the method I currently use for the heap-sorting, since it's more or less pre-sorted; thanks. I wanted to have the insight of other people too.
ΤΖΩΤΖΙΟΥ
Although this is splitting hairs a bit - you could still get O(n^2) behaviour on quicksort if you're unlucky, or if you take the first element of the array as the partition (as it's the smallest), and subsequent partitions might have the same problem.
HenryR
@Henry,Right.. Haven't thought about that case. I use median of three partitions, so the problem never occured when sorting heaps.
Nils Pipenbrinck
A: 

Since you already have a heap, couldn't you just use the second phase of the heap sort? It works in place and should be nice and efficient.

1800 INFORMATION
A: 

For in-place sorting, the fastest way follows. Beware of off-by-one errors in my code. Note that this method gives a reversed sorted list which needs to be unreversed in the final step. If you use a max-heap, this problem goes away.

The general idea is a neat one: swap the smallest element (at index 0) with the last element in the heap, bubble that element down until the heap property is restored, shrink the size of the heap by one and repeat.

This isn't the absolute fastest way for non-in-place sorting as David Mackay demonstrates http://users.aims.ac.za/~mackay/sorting/sorting.html">here - you can do better by putting an element more likely to be the smallest at the top of the heap instead of one from the bottom row.

Time complexity is T(n.log n) worst case - n iterations with possibly log n (the height of the heap) goes through the while loop.

for (int k=len(l)-1;k>0;k--){
swap( l, 0, k );
while (i*2 < k)
  {
int left = i*2;
int right = l*2 + 1;
int swapidx = i;
if ( l[left] < l[right] )
  {
    if (l[i] > l[left])
      {
 swapidx = left;
      }
  }
else
  {
    if (l[i] > l[right])
      {
 swapidx = right;
      }
  }

if (swapidx == i)
  {
    // Found right place in the heap, break.
    break;
  }
swap( l, i, swapidx );
i = swapidx;
  }}

// Now reverse the list in linear time:
int s = 0; 
int e = len(l)-1;
while (e > s)
  {
    swap( l, s, e );
    s++; e--:
  }
HenryR