
import java.io.*;
import java.lang.Math;

public class SortShell {
// a sorting shell for experiments with sorting algorithms

    public static void selectionSort (int [] a) {
	int k, index, temp;
	for (k = a.length-1; k >= 1; k--) {
	    //find the index of the maximum array element in A[0], ..., A[k]
	    int maxIndex = 0;  // as the search begins, the largest is at index 0
	    for (index = 1; index <= k; index++) {   //proceed through the array
		if (a[maxIndex] < a[index]) {       // update maxIndex when
		    maxIndex = index;                // something bigger is found
		}
	    }
	    
	    //swap largest with A[k]
	    temp = a[k];
	    a[k] = a[maxIndex];
	    a[maxIndex] = temp;
	}
    }
    
    public static void insertionSort (int [] a) {
	// method to sort using the insertion sort
	for (int k = 1; k < a.length; k++) {
	    int item = a[k];
	    int i = k-1;
	    while ((i >= 0) && a[i] > item){
		a[i+1] = a[i];
		i--;
	    }
	    a[i+1] = item;
	}
    } // insertionSort
    
    public static void mergeSort (int [] a) {
	System.out.print ("not yet implemented ");
    }
    
    public static void main (String [] args) {
	
        System.out.printf ("%60s", "Algorithm Timings\n");
	System.out.println ("  Sort           Data Size   Ascending Data    "
			    + "Random Data     Descending Data");
	
	int size;
	long start_time, end_time;
	for (size = 10000; size < 400000; size *= 2)
	    {
		
		//declaration of arrays
		int [] randData  = new int [size];
		int [] dataSet = new int [size];
		
		// initialize random array
		for (int i = 0; i < size; i++)
		    randData[i] = (int)(Math.random()*4*size);
		
		/***************************************************/
		// selection sort   selection sort   selectiontion sort
		System.out.printf ("%-15s %7d", "Selection", size);
		//ascending test
		for (int i = 0; i < size; i++)
		    dataSet[i] = 2*i;
		start_time = System.currentTimeMillis();
		selectionSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%12d", end_time-start_time);
		
		//random test
		for (int i = 0; i < size; i++)
		    dataSet[i] = randData[i];
		start_time = System.currentTimeMillis();
		selectionSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%20d", end_time-start_time);
		
		//descending test
		for (int i = 0; i < size; i++)
		    dataSet[i] = 2*size - 2*i;
		start_time = System.currentTimeMillis();
		selectionSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%18d\n", end_time-start_time);
		
		/***************************************************/
		// insertion sort   insertion sort   insertion sort
		System.out.printf ("%-15s %7d", "Insertion", size);
		//ascending test
		for (int i = 0; i < size; i++)
		    dataSet[i] = 2*i;
		start_time = System.currentTimeMillis();
		insertionSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%12d", end_time-start_time);
		
		//random test
		for (int i = 0; i < size; i++)
		    dataSet[i] = randData[i];
		start_time = System.currentTimeMillis();
		insertionSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%20d", end_time-start_time);
		
		//descending test
		for (int i = 0; i < size; i++)
		    dataSet[i] = 2*size - 2*i;
		start_time = System.currentTimeMillis();
		insertionSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%18d\n", end_time-start_time);
		
		/***************************************************/
		// merge sort   merge sort   merge sort   merge sort
		System.out.printf ("%-15s %7d", "Merge Sort", size);
		//ascending test
		for (int i = 0; i < size; i++)
		    dataSet[i] = 2*i;
		start_time = System.currentTimeMillis();
		mergeSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%12d", end_time-start_time);
		
		//random test
		for (int i = 0; i < size; i++)
		    dataSet[i] = randData[i];
		start_time = System.currentTimeMillis();
		mergeSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%20d", end_time-start_time);
		
		//descending test
		for (int i = 0; i < size; i++)
		    dataSet[i] = 2*size - 2*i;
		start_time = System.currentTimeMillis();
		mergeSort (dataSet); 
		end_time = System.currentTimeMillis();
		System.out.printf ("%18d\n\n", end_time-start_time);     
	    }
	
    } // main
} // SortShell
