040: // Based on the code at: 041: // http://clips.ee.uwa.edu.au/~morris/year2/PLDS210/Java/heap_sort/ComBox.class 042: // by John Morris, Centre for Intelligent Information Processing Systems 043: // Course notes for Programming Languages and Data Structures PLDS210 044: // The code presented here is based on the code attached to the animation 045: // of the Heap Sort, animation by Woi Ang. 046: // 047: // The original code does not compile because setHeapWithSize is not defined 048: // 049: // Simple substitution of an array for a heap will not work because of the 050: // intertwined use of .length. When an array is used for a heap, if frequent 051: // checks are to avoided, the size of the array must be one less than a 052: // power of 2 to allow all parents to have children. The original algorithm, 053: // however, uses .length to get the occupied portion of the heap. 054: // 055: // In this simple fix, we define a class, Heap, that combines an array with 056: // a length, and take the lazy way out, making the array bigger than in needs 057: // to be (twice the occupied size). For a space-efficient production version, 058: // the next power of 2 above the occupied size should be computed. 059: // 060: // Revisions by H. J. Bernstein, 10 March 2004. 061: 062: 063: public class HeapSort { 064: 065: public class Heap { 066: public int length; 067: public int [] array; 068: public Heap (int size) { 069: array = new int[size*2]; 070: length = size; 071: } 072: } 073: 074: public void heapsort(int [] a ) { 075: Heap A = setHeapWithSize(a, a.length); 076: buildHeap(A); 077: printHeap(A); 078: for (int i = a.length; i > 1; i--) { 079: a[i-1] = A.array[0]; A.array[0] = A.array[i-1]; 080: A = setHeapWithSize(A.array,A.length -1); 081: heapify(A, 1); 082: printHeap(A); 083: } 084: a[0] = A.array[0]; 085: } 086: 087: public void printHeap(Heap a ) { 088: for (int i = 0; 2*i+2 < a.length; i++) { 089: System.out.println("Node "+(i+1)+": "+a.array[i]+" Left: "+a.array[2*i+1]+ 090: " Right: "+a.array[2*i+2]); 091: } 092: } 093: 094: public Heap setHeapWithSize(int [] a, int len) { 095: Heap result; 096: result = new Heap(len); 097: for (int i = 0; i < len; i++) { 098: result.array[i] = a[i]; 099: } 100: return result; 101: } 102: 103: public void buildHeap(Heap a) { 104: for (int i = a.length/2; i > 0; i--) { 105: heapify(a,i); 106: } 107: } 108: 109: public void heapify(Heap a, int i) { 110: int l = left(i); 111: int r = right(i); 112: int largest; 113: if ( i < heapSize(a) && a.array[l-1] > a.array[i-1]) { 114: largest = l; 115: } else { 116: largest = i; 117: } 118: if ( r <= heapSize(a) && a.array[r-1] > a.array[largest -1]){ 119: largest = r; 120: } 121: if (largest != i) { 122: // exchange a[i], a[largest] 123: int tmp = a.array[i-1]; a.array[i-1] = a.array[largest-1]; 124: a.array[largest-1] = tmp; 125: heapify(a, largest); 126: } 127: } 128: 129: 130: public int heapSize(Heap a){ 131: return a.length; 132: } 133: 134: public int parent(int i) { 135: return (i/2); 136: } 137: 138: public int left(int i) { 139: return (2*i); 140: } 141: 142: public int right(int i) { 143: return (2*i + 1); 144: } 145: 146: }