0

I am working on a coms assignment and have hit a huge wall. We are working with quicksort / partition.

 /**
 * An implementation of the SELECT algorithm of Figure 1 of the project
 * specification. Returns the ith order statistic in the subarray
 * arr[first], ..., arr[last]. The method must run in O(n) expected time,
 * where n = (last - first + 1).
 * 
 * @param arr
 * - The data to search in
 * @param first
 * - The leftmost boundary of the subarray (inclusive)
 * @param last
 * - The rightmost boundary of the subarray (inclusive)
 * @param i
 * - The requested order statistic to find
 * @return - The ith order statistic in the subarray
 * 
 * @throws IllegalArgumentException
 * - If i < 1 or i > n
 */
public static int select(int[] arr, int first, int last, int i) {
    if(first == last){
        return first;
    }
    int pivot = (arr.length / 2);
    pivot = partition(arr, first, last, pivot-1);
    if(i == pivot){
        return arr[i];
    } else if(i < pivot){
        return select(arr, first, pivot-1, i);
    } else {
        return select(arr, pivot+1, last, i);
    }

}

The above is a 'select' method, I believe it is an implementation of quicksort. When I run it with my partition method, I keep getting errors of ArrayIndex out of bounds, I am wondering if the way I chose my pivot is causing these errors...

The below is a partition and a swap method I have written. The partition method works from what I can tell, I made a int[] of 10 and ran it multiple times, using different pivot points. Each time it threw out the arr sorted the way it should be.

    public static int partition(int[] arr, int first, int last, int pivot){     
    int pValue = arr[pivot];
    swap(arr, last, pivot);
    int temp = first;
    for (int i = first; i < last; i++) {
        if(arr[i] < pValue){
            swap(arr, temp, i);
            temp++;
        }
    }
    swap(arr, last, temp);
    return arr[pivot];
}

public static void swap(int[] arr, int a, int b){
    int temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
}

The rest of the assignment builds off of the select method, and I have been slamming me head into a wall for two days to get it to work correctly.... To the point actually where I am second guessing my choice in degree. I guess as a secondary question how many of you guys hit these walls and lost all confidence in yourselves? The last few assignments, with a bit of help, made sense, but now I am here and just lost in the dark...

PS. Sorry if I sound all sappy, it's been a rough weekend and the above has been a huge pain.

Kevvvvyp
  • 1,704
  • 2
  • 18
  • 38
Loomiss
  • 11
  • 1
  • 1
  • 6
  • 1
    Here is a tip: if you can't understand what is going on, put some `System.out.println` statements in the code at crucial points (e.g., method entry points); print out important values and then try and see what is actually happening. – rghome Feb 23 '15 at 16:45

1 Answers1

1

First off, the best way to debug this at this point is put print statements before every array access that prints what index is being looked at. This will tell you right away where the error is happening. The following is a guess at what might be happening. There may be other culprits.

  1. What happens if the pivot is the first or last element (like which will always happen on an array of 2 elements)? Then when you select on pivot + 1 or pivot - 1, as you do at the end of the select function, you'll go off the end of the array. Or when you partition on pivot - 1. It seems you need to flesh out the base case your recursive function. This is the most likely culprit.

  2. You're picking your pivot based on the length of the entire array rather than the length of the subarray, which is from first to last instead of from 0 to arr.length. If first and last have always been the the first and last element of the entire array, then I doubt this is the problem (though it still will be a problem when tested more thoroughly).

Alejandro
  • 1,168
  • 8
  • 11
  • This has been what I have been thinking for the greater part of last night into today, I am thinking the way I am doing my partition is incorrect. Essentially instead passing in a pivot in the partition, I think I should just break the Array (or subarray) in half. essentially for partition: if first != last than pivot = (last-first/2) than go through the actual partition. And return first. I think that I just got frustrated working with it and left the return in the partition in a weird point. Also for the select, I know I will recursively use the partition, it's just hard to visualize it. – Loomiss Feb 23 '15 at 17:43
  • Recursion can be tough to learn. Stick with it. When I was learning I found it helpful to draw out the steps that would happen on a whiteboard or with paper and pen. Good luck! – Alejandro Feb 23 '15 at 19:34