Connecting Tech Pros Worldwide Forums | Help | Site Map

Generic heap sort algorithm B

JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#1   May 4 '07
Welcome back to the Sorting article.

For completeness, so you can copy and paste this sorting utility straight
in your own private back of tricks, here is the entire class:

Expand|Select|Wrap|Line Numbers
  1. public final class HeapSort {
  2.  
  3.     private HeapSort() { } // no istances of this class possible
  4.  
  5.     // given a Sortable, build a heap starting at node i. There a n nodes in total
  6.     private static void heapify(Sortable s, int p, int n) {
  7.  
  8.         for (int r, l= (p<<1)+1; l < n; p= l, l= (p<<1)+1) {
  9.  
  10.             // l is the maximum of l and r, the two subnodes of p 
  11.             if ((r= l+1) < n && s.compare(l, r) < 0) l= r;
  12.  
  13.             // check if parent p is less than maximum l
  14.             if (s.compare(p, l) < 0) s.swap(p, l);
  15.             else break;
  16.         }
  17.  
  18.     // build a heap out of the Sortable in place
  19.     private static void phase1(Sortable s) {
  20.  
  21.         // heapify all the non-leaf nodes         
  22.         for (int n= s.length(), p= n/2; p >= 0; p--)
  23.             heapify(s, p, n);
  24.     }
  25.  
  26.     // sort the Sortable
  27.     private static void phase2(Sortable s) {
  28.  
  29.         for (int n= s.length(); --n > 0; ) {
  30.             s.swap(0, n);         // put the root element in its place
  31.             heapify(s, 0, n);     // and restore the heap again
  32.         }        
  33.     }
  34.  
  35.     // driver for the worked methods
  36.     public static Sortable sort(Sortable s) { 
  37.  
  38.         phase1(s);     // build initial heap
  39.         phase2(s);     // sort the sortable given the heap
  40.  
  41.         return s;     // return the Sortable for convenience
  42.     }
  43. }
  44.  
This class takes about one page of text in my VI text editor. Let's step back
a bit from this code and realize what we've just created: this sort algoritm is
very efficient and stable w.r.t. it's runtime. This implementation doesn't know
anything about what exactly needs to be sorted, i.e. it only uses the Sortable
interface.

The class is final and contains a private default constructor so there is no
way for anyone else to create an instance of a HeapSort object; because no such
object is needed: this class is a utility class with just functionality.

The first article explained a bit about the heap sort algorithm itself.
Now let's get back to our original problem: given the following two arrays:

Expand|Select|Wrap|Line Numbers
  1. String[] first= { "Fred", "Barney", "Wilma", "Betty", "Bambam", "Pebbles" };
  2. String[] last= { "Flintstone", "Rubble", "FlintStone", "Rubble", "Rubble", "Flintstone" };
  3.  
We have to create a Sortable that can return the number of first/last names, it
can compare two first names (for example) and it can swap two elements in both
the first and last name arrays. We need to sort these two array according to
the first name; the other array just needs to 'follow' i.e it last names must
correspond to the first names after the sort has finished.

Here's the complete example without many comments:

Expand|Select|Wrap|Line Numbers
  1. public class Flintstones implements Sortable {
  2.  
  3.     private String[] first;
  4.     private String[] last;
  5.  
  6.     public FlintStones(String[] first, String[] last) {
  7.  
  8.         this.first= first;
  9.         this.last = last;
  10.     }
  11.  
  12.     public int length() { // interface implementation
  13.  
  14.         return first.length; 
  15.     } 
  16.  
  17.     public int compare(int i, int j) { // interface implementation
  18.  
  19.         return first[i].compareTo(first[j]);
  20.     }
  21.  
  22.     private void swap (String[] s, int i, int j) { // private helper method
  23.  
  24.         String t= s[i]; s[i]= s[j]; s[j]= t;
  25.  
  26.     }
  27.     public void swap(int i, int j) { // interface implementation
  28.  
  29.         swap(first, i, j);
  30.         swap(last, i, j);
  31.     }
  32.  
  33.     public static void main(String[] args) {
  34.  
  35.         String[] first= { "Fred", "Barney", "Wilma", "Betty", "Bambam", "Pebbles" };
  36.         String[] last= { "Flintstone", "Rubble", "FlintStone", "Rubble", "Rubble", "Flintstone" };
  37.  
  38.         HeapSort.sort(new ArraySortable(first, last));
  39.  
  40.         for (int i= 0; i < first.length; i++)
  41.             System.out.println(first[i]+" "+last[i]);
  42.     }
  43. }
  44.  
So what was this 'Tip Of The Week' all about? It showed that you can sort not
just arrays or Lists, but anything that implements the Sortable interface. It
also showed some of the gory details of the heap sort algorithm.

If I don't get kicked out now I'd like to tell something about permutations
and combinations in a next Tip Of The Week and how they can be efficiently
generated without much hassle.

kind regards,

Jos



Closed Thread