public class HeapSort3
{
		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;

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

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

						System.out.println("hole="+hole+" child="+child);

						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];
						}
						else
								break;
				}
				
				array[hole] = tmp;
		}

		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);
				
				
		}
	

}