1  /**
  2     This class applies the heapsort algorithm to sort an array.
  3  */
  4  public class HeapSorter
  5  {
  6     private int[] a;
  7  
  8     /**
  9        Constructs a heap sorter that sorts a given array.
 10        @param anArray an array of integers
 11     */
 12     public HeapSorter(int[] anArray)
 13     {
 14        a = anArray;
 15     }   
 16  
 17     /**
 18        Sorts the array managed by this heap sorter.
 19     */
 20     public void sort()
 21     {  
 22        int n = a.length - 1;
 23        for (int i = (n - 1) / 2; i >= 0; i--)
 24           fixHeap(i, n);
 25        while (n > 0)
 26        {
 27           swap(0, n);
 28           n--;
 29           fixHeap(0, n);
 30        }
 31     }
 32  
 33     /**
 34        Ensures the heap property for a subtree, provided its
 35        children already fulfill the heap property.
 36        @param rootIndex the index of the subtree to be fixed
 37        @param lastIndex the last valid index of the tree that 
 38        contains the subtree to be fixed
 39     */
 40     private void fixHeap(int rootIndex, int lastIndex)
 41     {
 42        // Remove root
 43        int rootValue = a[rootIndex];
 44  
 45        // Promote children while they are larger than the root      
 46  
 47        int index = rootIndex;
 48        boolean more = true;
 49        while (more)
 50        {
 51           int childIndex = getLeftChildIndex(index);
 52           if (childIndex <= lastIndex)
 53           {
 54              // Use right child instead if it is larger
 55              int rightChildIndex = getRightChildIndex(index);
 56              if (rightChildIndex <= lastIndex
 57                    && a[rightChildIndex] > a[childIndex])
 58              {
 59                 childIndex = rightChildIndex;
 60              }
 61              
 62              if (a[childIndex] > rootValue) 
 63              {
 64                 // Promote child
 65                 a[index] = a[childIndex];
 66                 index = childIndex;
 67              }
 68              else
 69              {
 70                 // Root value is larger than both children
 71                 more = false;
 72              }
 73           }
 74           else 
 75           {
 76              // No children
 77              more = false; 
 78           }
 79        }
 80  
 81        // Store root value in vacant slot
 82        a[index] = rootValue;
 83     }
 84  
 85     /**
 86        Swaps two entries of the array.
 87        @param i the first position to swap
 88        @param j the second position to swap
 89     */
 90     private void swap(int i, int j)
 91     {
 92        int temp = a[i];
 93        a[i] = a[j];
 94        a[j] = temp;
 95     }
 96  
 97     /**
 98        Returns the index of the left child.
 99        @param index the index of a node in this heap
100        @return the index of the left child of the given node
101     */
102     private static int getLeftChildIndex(int index)
103     {
104        return 2 * index + 1;
105     }
106  
107     /**
108        Returns the index of the right child.
109        @param index the index of a node in this heap
110        @return the index of the right child of the given node
111     */
112     private static int getRightChildIndex(int index)
113     {
114        return 2 * index + 2;
115     }
116  }