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 }