public class HeapSort2
{
		public static <AnyType> void printArray(AnyType[] array)
		{
				System.out.print("[");
				
				for (int i=0 ; i<array.length ; i++)
						System.out.print(array[i]+" ");

				System.out.println("]");				
		}

		public static <AnyType> void swapReferences(AnyType[] array, int i, int j)
		{
				AnyType tmp = array[i];
				array[i] = array[j];
				array[j] = tmp;
		}

		public static <AnyType extends Comparable<? super AnyType>>
																								void heapSort(AnyType[] array)
		{
				// Build Heap
				for (int i=array.length/2-1 ; i>=0 ; i-- )
				{
						percDown(array, i, array.length);
				}

				printArray(array);

				for (int i=array.length-1 ; i>0 ; i-- )
				{
						swapReferences( array, 0, i ); // deleteMax
						percDown( array, 0, i); // Maintain heap ordering property
				}

		}

			public static <AnyType extends Comparable<? super AnyType>>
																										void percDown(AnyType[] array, int hole, int size)
		{
				int child;

				AnyType tmp = array[hole];
				System.out.println("hole="+hole+" size="+size);
				

				System.out.println("Percolating a["+hole+"]="+array[hole]);
				
				child = hole * 2 + 1;

				if (child>=size)
						return;

				if ((child+1)!=size && array[child+1].compareTo(array[child]) > 0)
						// Left child is not last and Right child is bigger
						child++;
				if (array[child].compareTo(tmp) > 0)
				{
						// Child is bigger than percolating item
						System.out.println("Moved up a["+child+"]="+array[child]+
																									", down a["+hole+"]="+tmp);								
				
						array[hole] = array[child];
						array[child] = tmp;
						percDown(array, child, size);
				}
		}

		public static void main(String[] args)
		{
				Integer array[] = new Integer[15];

				for (int i=0 ; i<array.length ; i++)
						array[i] = (int)(100*Math.random());

				System.out.println("Before: ");
				printArray(array);

				heapSort(array);

				System.out.println("After:");
				printArray(array);
				
				
		}
	

}