|
Comp202: Principles of Object-Oriented Programming II
|
public int split(int[] A, int lo, int hi) {
// Swap A[hi] and A[lo].
int temp = A[hi];
A[hi] = A[lo];
A[lo] = temp;
// Restore the heap property by ``sifting down''
// the element at A[lo].
Heapifier.Singleton.siftDown(A, lo, lo, hi - 1);
return hi;
}
public void siftDown(int[] A, int lo, int cur, int hi) {
int dat = A[cur]; // hold on to data.
int child = 2 * cur + 1 - lo; // index of left child of A[cur].
boolean done = hi < child;
while (!done) {
if (child < hi && A[child + 1] < A[child]) {
child++;
} // child is the index of the smaller of the two children.
if (A[child] < dat) {
A[cur] = A[child];
cur = child;
child = 2 * cur + 1 - lo;
done = hi < child;
} // A[cur] is less than its children.
else { // A[cur] <= A[child].
done = true; // heap condition is satisfied.
} // A[cur] is less than its children.
} // location found for temp.
A[cur] = dat;
}
In order to sort an array, using the ordering capabilities of a heap, you must first transform the randomly placed data in the array into a heap. This is called "heapifying" the array. This can be accomplished by sifting down the elements. Luckily, even though this operation takes place in O(n log(n)) time, it only occurs once, so in the end, it has no impact on the overall complexity of the algorithm.
Note that we only really have to sift down half the array, i.e. half the "tree". This is because a single-element array (tree) is already a heap, so we can bypass all the leaves and immediately start working on the layer right above the leaves.
public class HeapSorter extends ASorter {
public HeapSorter(int[] A, int lo, int hi) {
for (int cur = (hi + lo + 1) / 2; cur >= lo; cur--) {
Heapifier.Singleton.siftDown(A, lo, cur, hi);
}
}
// etc. . .
}
/** * "Sifts" A[cur] up the array A to maintain the heap property. * @param A A[lo:cur-1] is a heap. * @param lo the low index of A. * @param cur lo <= cur <= the high index of A. */ public void siftUp(int[] A, int lo, int cur) { int dat = A[cur]; int parent = (cur - lo - 1) / 2 + lo; // index of parent. while (0 < (cur - lo) && dat < A[parent]) { A[cur] = A[parent]; cur = parent; parent = (cur - lo - 1) / 2 + lo; } A[cur] = dat; }
Best-case Cost | Worst-case Cost | |
Selection | O(n2) | O(n2) |
Insertion | O(n) | O(n2) |
Heap | O(n log n) | O(n log n) |
Merge | O(n log n) | O(n log n) |
Quick | O(n log n) | O(n2) |
Last Revised Thursday, 03-Jun-2010 09:52:35 CDT
©2007 Stephen Wong and Dung Nguyen