I have three classes. Each creates an array of 1000 int values.

* class a: uses QuickSort
* class b: uses QuickSort until the size of each partition is <10 then executes InsertSort for sorting the smaller partitions.
* class c: (this is the one I'm having trouble with): same as class b except executes InsertSort on the whole almost sorted array.

It would seem that class c is only a slight variation of the code in class b (which basically adds to class a). I just don't really know HOW to make this happen... Help! Thanks in advanced... 

Class a: 

```
import java.util.Arrays;
import java.util.Random;

public class QuickSort {

private static final Random random = new Random();
private static final int RANDOM_INT_RANGE = 9999;

private static int[] randomArray(int size) {

    // Randomize data (array)
    final int[] arr = new int[size];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = random.nextInt(RANDOM_INT_RANGE);
    }
    return arr;
}

// Sort
private static void sort(int[] arr) {
    if (arr.length > 0)
        sortInPlace(arr, 0, arr.length - 1);
}

private static void sortInPlace(int[] arr, int left, int right) {

    if (left >= right)
        return; // sorted

    final int range = right - left + 1;
    int pivot = random.nextInt(range) + left;

    int newPivot = partition(arr, left, right, pivot);

    sortInPlace(arr, left, newPivot - 1);
    sortInPlace(arr, newPivot + 1, right);

}

private static int partition(int[] arr, int left, int right, int pivot) {

    int pivotVal = arr[pivot];
    swapArrayVals(arr, pivot, right);

    int storeIndex = left;
    for (int i = left; i <= (right - 1); i++) {
        if (arr[i] < pivotVal) {
            swapArrayVals(arr, i, storeIndex);
            storeIndex++;
        }
    }

    swapArrayVals(arr, storeIndex, right);

    return storeIndex;
}

private static void swapArrayVals(int[] arr, int from, int to) {
    int fromVal = arr[from];
    int toVal = arr[to];
    arr[from] = toVal;
    arr[to] = fromVal;
}

public static void main(String[] args) {

    long StartTime = System.nanoTime();

    // Array size
    int[] arr = randomArray(1000);
    int[] copy = Arrays.copyOf(arr, arr.length);

    // Print original data (array)
    System.out.println("The starting/unsorted array: \n"
            + Arrays.toString(arr));

    sort(arr);

    // check the result
    Arrays.sort(copy);
    if (Arrays.equals(arr, copy)) {
        System.out.println("The ending/sorted array: \n"
                + Arrays.toString(arr));

        // print time
        long TotalTime = System.nanoTime() - StartTime;
        System.out.println("Total elapsed time (milliseconds) " + "is: "
                + TotalTime);
    }

}
}

```

Class b: 

```
import java.util.Arrays;
import java.util.Random;

public class OptQSort1 {
private static final Random random = new Random();
private static final int RANDOM_INT_RANGE = 9999;

private static int[] randomArray(int size) {

    // Randomize data (array)
    final int[] arr = new int[size];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = random.nextInt(RANDOM_INT_RANGE);
    }
    return arr;
}

// Sort
private static void sort(int[] arr) {
    if (arr.length > 0)
        sortInPlace(arr, 0, arr.length - 1);
}

private static void sortInPlace(int[] arr, int left, int right) {

    boolean insertionSortCalled = false;

    // OptQSort1:
    int size = right - left + 1;
    if (size < 10 && !insertionSortCalled) {
        insertionSortCalled = true;
        insertionSort(arr, 0, arr.length - 1);
    }

    if (left >= right)
        return; // sorted

    final int range = right - left + 1;
    int pivot = random.nextInt(range) + left;

    int newPivot = partition(arr, left, right, pivot);

    sortInPlace(arr, left, newPivot - 1);
    sortInPlace(arr, newPivot + 1, right);

}

private static int partition(int[] arr, int left, int right, int pivot) {

    int pivotVal = arr[pivot];
    swapArrayVals(arr, pivot, right);

    int storeIndex = left;
    for (int i = left; i <= (right - 1); i++) {
        if (arr[i] < pivotVal) {
            swapArrayVals(arr, i, storeIndex);
            storeIndex++;
        }
    }

    swapArrayVals(arr, storeIndex, right);

    return storeIndex;
}

private static void swapArrayVals(int[] arr, int from, int to) {
    int fromVal = arr[from];
    int toVal = arr[to];
    arr[from] = toVal;
    arr[to] = fromVal;
}

public static void insertionSort(int[] arr, int left, int right) {
    int in, out;

    for (out = left + 1; out <= right; out++) {
        int temp = arr[out];
        in = out;

        while (in > left && arr[in - 1] >= temp) {
            arr[in] = arr[in - 1];
            --in;
        }
        arr[in] = temp;
    }

}

public static void main(String[] args) {

    long StartTime = System.nanoTime();

    // Array size
    int[] arr = randomArray(1000);
    int[] copy = Arrays.copyOf(arr, arr.length);

    // Print original data (array)
    System.out.println("The starting/unsorted array: \n"
            + Arrays.toString(arr));

    sort(arr);

    // check the result
    Arrays.sort(copy);
    if (Arrays.equals(arr, copy)) {
        System.out.println("The ending/sorted array: \n"
                + Arrays.toString(arr));

        // print time
        long TotalTime = System.nanoTime() - StartTime;
        System.out.println("Total elapsed time (milliseconds) " + "is: "
                + TotalTime);
    }
}

}

```

Class c: 

```
import java.util.Arrays;
import java.util.Random;

public class OptQSort2 {

private static final Random random = new Random();
private static final int RANDOM_INT_RANGE = 9999;

private static int[] randomArray(int size) {

    // Randomize data (array)
    final int[] arr = new int[size];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = random.nextInt(RANDOM_INT_RANGE);
    }
    return arr;
}

// Sort
private static void sort(int[] arr) {
    if (arr.length > 0)
        sortInPlace(arr, 0, arr.length - 1);
    insertionSort(arr, 0, arr.length - 1);
}

private static void sortInPlace(int[] arr, int left, int right) {

    // OptQSort2:
    int size = right - left + 1;

    if (size < 10)
        return;

    if (left >= right)
        return; // sorted

    final int range = right - left + 1;
    int pivot = random.nextInt(range) + left;

    int newPivot = partition(arr, left, right, pivot);

    sortInPlace(arr, left, newPivot - 1);
    sortInPlace(arr, newPivot + 1, right);

}

private static int partition(int[] arr, int left, int right, int pivot) {

    int pivotVal = arr[pivot];
    swapArrayVals(arr, pivot, right);

    int storeIndex = left;
    for (int i = left; i <= (right - 1); i++) {
        if (arr[i] < pivotVal) {
            swapArrayVals(arr, i, storeIndex);
            storeIndex++;
        }
    }

    swapArrayVals(arr, storeIndex, right);

    return storeIndex;
}

private static void swapArrayVals(int[] arr, int from, int to) {
    int fromVal = arr[from];
    int toVal = arr[to];
    arr[from] = toVal;
    arr[to] = fromVal;
}

public static void insertionSort(int[] arr, int left, int right) {
    int in, out;

    for (out = left + 1; out <= right; out++) {
        int temp = arr[out];
        in = out;

        while (in > left && arr[in - 1] >= temp) {
            arr[in] = arr[in - 1];
            --in;
        }
        arr[in] = temp;
    }

}

public static void main(String[] args) {

    // Start the clock
    long StartTime = System.nanoTime();

    // Array size
    int[] arr = randomArray(1000);
    int[] copy = Arrays.copyOf(arr, arr.length);

    // Print original data (array)
    System.out.println("The starting/unsorted array: \n"
            + Arrays.toString(arr));

    sort(arr);

    // check the result
    Arrays.sort(copy);
    if (Arrays.equals(arr, copy)) {
        System.out.println("The ending/sorted array: \n"
                + Arrays.toString(arr));

        // print time
        long TotalTime = System.nanoTime() - StartTime;
        System.out.println("Total elapsed time (milliseconds) " + "is: "
                + TotalTime);
    }
}

}

```