First of all I'm just going to state that this is a homework question which I have made an extensive amount of attempts on.
I've been asked to modify quicksort in Java to set the pivot as the psuedo median of 9 values in the array using the formula i * (n-1) /8
I wrote a computeMedian
method which accepts 3 integers, determines the highest, and then returns that value.
The code:
public static int computeMedian(int x, int y, int z)
{
if((x >= y && x <= z) || (x >= z && x <= y)) {return x;}
else if((y >= x && y <= z) || (y >= z && y <= x)) {return y;}
else if((z >= x && z <= y) || (z >= y && z <= x)) {return z;}
else { return 0; }
}
I then used it in my findPivot
method which takes the current array, from, to
values and uses them to construct a pivot
Here is that code:
public static int findPivot(int[] a, int from, int to)
{
if(a.length <= 7)
{
return a[(to)/2];
}
else if(a.length > 7 && a.length <= 40)
{
return computeMedian(a[from], a[(to)/2] , a[to]);
}
else
{
int x = computeMedian(a[0 * (to) / 8], a[1 * (to) / 8], a[2 * (to) / 8]);
int y = computeMedian(a[3 * (to) / 8], a[4 * (to) / 8], a[5 * (to) / 8]);
int z = computeMedian(a[6 * (to) / 8], a[7 * (to) / 8], a[8 * (to) / 8]);
return computeMedian(x,y,z);
}
}
This method is working fine for sorting any array less than or equal to size 40, but as soon as it gets larger than 40 I recieve a stack overflow error leading back to my computeMedian
method in the else {}
portion. I will note that return computeMedian(a[from], a[(to)/2] , a[to]);
works in the > 40 portion if I put it there, but that is only the median of 3 values as opposed to the median of the median of 3 sets.
Currently this is how I have findPivot
plugged into the quicksort partitioning method:
private static int modPartition(int[] a, int from, int to)
{
int pivot = findPivot(a, from, to);
int i = from - 1;
int j = to + 1;
while(i < j)
{
i++; while (a[i] < pivot) { i++; }
j--; while (a[j] > pivot) { j--; }
if (i < j) { swap(a, i, j); }
}
return j;
}
I'm pretty much stumped on why my computeMedian
method fails to work on larger datasets. I've tried placing the i * (n-1) / 8
values in an array via a for loop, sorting them and returning the value in the middle as well as placing the values in an array p
and calling computeMedian(computeMedian(p[0], p[1], p[2]), computeMedian(p[3],p[4],p[5]),...etc
and I get the same stack overflow issue but it tends to move around to different portions of my code and leading me in circles.
I can post any more snippets if anyone needs but I think my issue is right here probably.
Thanks for the help. I'm still learning and I think getting a grip on this would totally help me problem solve in the future on my own.
Here are the problem lines from the stack trace:
Line 16: int p = modPartition(a, from, to);
Line 18 modSort(a, p+1, to);
Line 23 int pivot = findPivot(a, from, to);
Heres my entire modSort method also:
public static void modSort(int[]a, int from, int to)
{
if(from >= to) { return; }
int p = modPartition(a, from, to);
modSort(a, from, p);
modSort(a, p+1, to);
}