/**
 * This class provides code for a linear search, binary search, 
 * and insertion sort, as standard algorithms covered when
 * introducing algorithmic analysis.
 */
public class AlgsForAnalysis
{

    /**
     * linear search algorithm
     * @returns index where item is stored in array, if present
     *          -1 otherwise
     */
    public static int linearSearch (int arr [], int item)
    {
        int i;
        for (i = 0; i < arr.length; i++)
            {
                if (arr[i] == item)
                    return i;
            }
        /* item not found */
        return -1;
    }

    /**
     * binary search algorithm
     * precondition:  array sorted in ascending order
     * @returns index where item is stored in array, if present
     *          -1 otherwise
     */
    public static int binarySearch (int arr [], int item)
    {
        int left = 0;
        int right =  arr.length;
        while (left < right)
            {
                int mid = (left + right) / 2;
                if (arr[mid] == item)
                    return mid;
                if (arr[mid] < item)
                    left = mid + 1;
                else
                    right = mid;
            }
        /* item not found */
        return -1;
    }

    /**
     * insertion sort algorithm
     * array sorted into ascending order
     */
    public static void insertionSort (int arr[])
    {
        for (int k = 1; k < arr.length; k++) {
            int item = arr[k];
            int i = k-1;
            while ((i >= 0) && arr[i] > item){
                arr[i+1] = arr[i];
                i--;
            }
            arr[i+1] = item;
        }
    }

    /**
     * print values within an array
     */
    public static void print (int arr[])
    {
        System.out.print("array indices:");
        int i;
        for (i = 0; i < arr.length; i++)
            System.out.print ("\t" + i);
        System.out.println();
        System.out.print("array values: ");
        for (i = 0; i < arr.length; i++)
            System.out.print ("\t" + arr[i]);
        System.out.println();    
    }
        
    /**
     * testing for searching and sorting algorithms
     */
    public static void main (String args[])
    {
        int a1 [] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 8};
        print (a1);
        System.out.println ("linear search testing");
        System.out.println ("  search for -2 returns " + linearSearch(a1, -2));
        System.out.println ("  search for  3 returns " + linearSearch(a1,  3));
        System.out.println ("  search for  5 returns " + linearSearch(a1,  5));
        System.out.println ("  search for  8 returns " + linearSearch(a1,  8));
        System.out.println ("  search for  9 returns " + linearSearch(a1,  9));
        System.out.println ("  search for 10 returns " + linearSearch(a1, 10));
        insertionSort (a1);
        System.out.println ("result of insertion sort");
        print (a1);
        System.out.println ("binary search testing");
        System.out.println ("  search for -2 returns " + binarySearch(a1, -2));
        System.out.println ("  search for  3 returns " + binarySearch(a1,  3));
        System.out.println ("  search for  5 returns " + binarySearch(a1,  5));
        System.out.println ("  search for  8 returns " + binarySearch(a1,  8));
        System.out.println ("  search for  9 returns " + binarySearch(a1,  9));
        System.out.println ("  search for 10 returns " + binarySearch(a1, 10));
    }
}
