Attempting to implement QuickSort using Hoare Partition Scheme, but I am running into a problem where changing the index of the pivot causes overflow, regardless of array size. Code:
public void quickSort(int[] l, int min, int max){
if (min < max){
int p = partition(l, min, max);
quickSort(l, min, p);
quickSort(l, p+1, max);
}
}
public int partition(int[] l, int min, int max){
int pivot = l[min];
int i = min - 1;
int j = max +1;
while(true){
do{
i++;
}while(l[i] < pivot);
do{
j--;
}while(l[j] > pivot);
if (i >= j) {
return j;
}
//Swap
int temp = l[i];
l[i] = l[j];
l[j] = temp;
}
}
This implementation chooses the low-index (named min here) as the pivot element, and this works just fine. However, changing the pivot element to any other index, causes a StackOverflow Error regardless of the size of the array that is being sorted. (Error refers to line 3, where partition() is called) I would preferably have the pivot element chosen at random within the (min,max) range. What is causing this?
EDIT: The array used is generated as follows:
public static int[] generateRandomArray(int size, int lower, int upper){
int[] random = new int[size];
for (int i = 0; i < random.length; i++) {
int randInt = ThreadLocalRandom.current().nextInt(lower, upper+1);
random[i] = randInt;
}
return random;
}
In one of the Overflow cases I used this:
genereateRandomArray(10, 0, 9);
For some concrete examples, running the code above but changing the pivot element to say, l[max-1] or l[min+1], l[min+2] etc gives StackOverflow on my end.
The solution to my problem was as user MBo pointed out to swap the pivot element to the first index of the array, as the algorithm itself relies on the pivot being on index 0. This is what I had overlooked. (int i = min - 1; is correct however, and stays that way.)
We can see that at the first step i
becomes equal to min
, comparison of pivot element with itself fails and increment does not occur more:
int pivot = l[min];
int i = min - 1;
...
do{
i++;
}while(l[i] < pivot);
Exclude pivot element from comparison (int i = min;
) and exchange it with partition one (seems l[j]
) at the end