Im trying to make a Quicksort but it always showing up the Error ArrayIndexOutOfBoundsException.
public class Quicksort
{
void sort(int[] arr)
{
_quicksort(arr, 0, arr.length - 1);
}
private void _quicksort(int[] arr, int left, int right)
{
int pivot = (left + right)/2;
int l = left;
int r = right;
while (l <= r)
{
while (arr[l] < pivot)
{
l++;
}
while (arr[r] > pivot)
{
r--;
}
if(l <= r)
{
int temp = l;
l = r;
r = temp;
l++;
r++;
}
}
if(left < r)
{
_quicksort(arr, left, r);
}
if(l < right)
{
_quicksort(arr, l, right);
}
}
}
Does someone know why it doesnt run? It always gives a Error.
The Error message is
java.lang.ArrayIndexOutOfBoundsException: -1
at Quicksort._quicksort(Quicksort.java:18)
at Quicksort._quicksort(Quicksort.java:33)
at Quicksort.sort(Quicksort.java:5)
It seems like there are a couple of issues with your code. I've listed them below:
The variable pivot
stores the index of the pivot element and not the actual value. So, you can't use pivot
for comaparison as you have done in the 2 nested while loops. You need arr[pivot]
instead of pivot
there.
Imagine arr
looks like {1, 1, 1, 3, 2, 2, 2}
. Here, pivot
will be equal to 3
i.e. arr[pivot]
will be equal to 3
. Now, after both the nested while loops terminate, l
will be equal to 3
and r
will remain equal to 6
. You then swap arr[l]
and arr[r]
and increment both l
and r
. Since l
is still less than equal to r
, the outer while loop runs for a second time and you'll get an ArrayIndexOutOfBoundsExecption
when the control reaches the second nested while loop. This happens because you're trying to access arr[7]
(Out of Bounds).
Here's my code:
class Quicksort
{
void sort(int[] arr)
{
myQuicksort(arr, 0, arr.length - 1);
}
private void myQuicksort(int[] arr, int l, int r) {
if (l >= r) {
return;
}
int pivotIndex = (l + r) / 2;
swap (arr, r, pivotIndex);
int pivotValue = arr[r];
int swapIndex = 0;
int currentIndex = 0;
while (currentIndex != r) {
if (arr[currentIndex] < pivotValue) {
swap(arr, currentIndex, swapIndex);
swapIndex++;
}
currentIndex++;
}
swap(arr, r, swapIndex);
myQuicksort(arr, l, swapIndex - 1);
myQuicksort(arr, swapIndex + 1, r);
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
public class Main{
public static void main(String[] args) {
Quicksort quicksort = new Quicksort();
int[] arr = {3, 7, 1, 0, 4};
quicksort.sort(arr);
for (int i : arr) {
System.out.println(i);
}
}
}
You should read up on Quicksort. But here are the main points:
Choose a random pivot element and swap it with the last element. This makes the implementation much simpler.
Loop over the input array and keep a track of a swapIndex
such that everything before the swapIndex
is less than the pivotValue
and everything from the swapIndex
till the currentIndex
is greater than (or equal) the pivotValue
.
After the loop runs out, swap the element at swapIndex
with the pivot
. This inserts the pivot
in its correct position.
The pivot
divides the array into 2 subarrays. Call myQuicksort
on these 2 subarrays.