I am trying to select the median as the pivot in this app but seems like I am doing something wrong. Any help will be greatly appreciated.
I get the first few numbers in order and then towards the end.
public class QuickSort {
public static void main(String[] args) {
int [] list = {1,3,2,4,6,5,8,7,9,0};
quickSort (list);
for (int i=0; i < list.length; i++)
System.out.print(list[i] + " ");
}
public static void quickSort(int [] list)
{
quickSort(list, 0, list.length - 1);
}
public static void quickSort (int[] list, int first, int last)
{
int size = last - first + 1;
if (size > 3){
int median1 = median(list, first, last);
int partition1 = partition(list, first, last, median1);
quickSort(list, first, partition1 - 1);
quickSort(list, partition1 + 1, last);
}
}
public static int median(int [] list, int first1, int last1){
int middle = (first1 + last1)/2;
if (list[first1] > list[middle])
swap(list, first1, middle);
if (list[first1] > list[last1])
swap(list, first1, last1);
if (list[middle] > list[last1])
swap(list, middle, last1);
swap(list, middle, last1 - 1);
return list[last1 - 1 ];
}
public static int partition(int [] list, int left, int right, long pivot) {
int leftPtr = left;
int rightPtr = right - 1;
while (true) {
while (list[++leftPtr] < pivot);
while (list[--rightPtr] > pivot);
if (leftPtr >= rightPtr)
break;
else
swap(list, leftPtr, rightPtr);
}
swap(list, leftPtr, right - 1);
return leftPtr;
}
public static void swap(int []list, int dex1, int dex2) {
int temp = list[dex1];
list[dex1] = list[dex2];
list[dex2] = temp;
}
I get some numbers in order, but not all of them.
There are usually two approaches you can use to computer programming. You can either a) Take something that works and start removing/changing stuff until you get what you like. or b) Take the smallest case you can -- make it work -- and then keep on adding more complexicity.
In this case I suggest b) (FYI b) is usuall the best approach)
If you start with int[] list = { 3, 1, }, you can see that your list doesn't get sorted correctly.
This is because your quickSort function is only sorting lists of size greater than 3. In your case this condition should probably be "size > 1" -- though there may be some more things you need to do in order to get things working.
There's lot of info about QuickSort on wikipedia:
http://en.wikipedia.org/wiki/Quicksort
Related
try {
for (i = 0; i < data.length; i++) {
working[i] = data[i];
}
FileWriter fw3 = new FileWriter("quicksort.dat");
long startTime3 = System.nanoTime();
quickSort(working,0, working.length - 1);
long endTime3 = System.nanoTime();
long totalTime3 = endTime3 - startTime3;
System.out.println("The time to complete the quick sort was :" + totalTime3 + " nano seconds");
for (i = 0; i < working.length; i++) {
fw3.write(Integer.toString(working[i]) + "\n");
}
System.out.println("The file has been sorted by quick sort and output to quicksort.dat \n");
fw3.close();
} catch (IOException e) {
System.out.println(e);
}
static void quickSort(int data[], int left, int right) {
int i, j;
int partition;
if (right > left) {
partition = data[right];
i = left - 1;
j = right;
for (;;) {
while (data[++i] < partition);
while (data[--j] > partition);
if (i >= j) {
break;
}
swap(data[i], data[j]);
swap(data[i], data[right]);
quickSort(data, left, i - 1);
quickSort(data, i + 1, right);
}
}
}
static void swap(int left, int right) {
int array[] = new int[19];
int temp = array[left];
array[left] = array[right];
array[right]=temp;
This is just snippets of the code whole program is other sorts. I get an out bounds error every time it gets down to the quicksort function. I use 19 as my array because that is how big the file is I have tried 20 to see if it fixes it with no luck.
EDIT: I provided updated code down below to reflect changes that were made I still get an out of bounds error.
static void quickSort(int data[], int left, int right) {
int i, j;
int partition;
if (right > left) {
partition = data[right];
i = left - 1;
j = right;
for (;;) {
while (data[++i] < partition);
while (data[--j] > partition);
if (i >= j) {
break;
}
swap(data, i, j);
swap(data, i, right);
quickSort(data, left, i - 1);
quickSort(data, i + 1, right);
}
}
}
static void swap(int array[], int left, int right) {
int temp = array[left];
array[left] = array[right];
array[right] = temp;
}
You have declared swap as :
void swap(int left, int right)
So the arguments are the indexes into the array.
However, you call it with :
swap(data[i], data[j]);
So you are passing the VALUES in the array.
Try changing the call to :
swap(i, j);
EDIT TO ADD:
It must be pointed out that the issue above is just ONE issue with the sorting algorithm presented. Another problem is that the swap algorithm does not actually swap anything. It creates a local array variable array, operates on that and then returns (so discarding that local variable).
If your assignment is to output a sorted list of numbers, and that the numbers must be sorted using the sorting code presented - then that assignment is impossible because the sorting code presented is hopelessly flawed as a sorting algorithm; it does NOT sort (as you have found yourself), and has blatant severe issues compared to a correct implementation of quicksort (eg, you can compare to the answer here : https://stackoverflow.com/a/63811974/681444 )
EDIT TO ADD FOLLOWING REVISED CODE:
The revised sorting code is STILL hopelessly busted. It is not a correct implementation of QuickSort, and still does not sort correctly.
For example, I tried running it with the final element being the largest :
int data[] = {23, 8, 19, 35, 2, 12, 7, 64 };
Result : No sorting - the method hit the if (i >= j) {break;} with i==7 and j==6 straight off and so did nothing.
By contrast, the method in the answer I linked to above sorted correctly, so you can compare the method you have been given against that - or against other established articles (eg, do an internet search for java quicksort, there are plenty around)
As already noted by 'racraman', the sort definitely requires fixing.
Try re-implementing the sort function with the following method signature.
void sort(int[] arr, int leftIndex, int rightIndex) {
// swap code goes here
}
So, apparently there are cases in which my algorithm needs less changes of pivot to complete the sorting of the list. My algorithm does in fact sort the list correctly but the Number of pivots is less or equal to the examples I have been given.
One example given in my assignment is this array:
3 45 12 -3 4 -3 21 0 6 20
This is how the Output is supposed to look like:
Number of pivots: 7
First Element: -3
Last Element: 45
This is what I get:
Number of pivots: 5
First Element: -3
Last Element: 45
With another example it works with the right amount of pivots:
9 2 4 7 3 7 10 11 12 13 13 10 13 13
What I should get and also what I get:
Number of pivots: 10
First Element: 2
Last Element: 13
I'm especially confused that it works in some cases and in others it doesnt.
Here is the code:
public static void quickSort(int[] arr, int start, int end, CountObject count){
int partition = partition(arr, start, end, count);
//partition will return the position the pivot. The pivot will be at the right place, hence if either side
//of the pivot consists of only one element, it should not be sorted
//check whether the part left from the pivot should still be sorted
if(partition-1>start) {
quickSort(arr, start, partition - 1, count);
}
//check whether the part right from the pivot should still be sorted
if(partition+1<end) {
quickSort(arr, partition + 1, end, count);
}
}
public static int partition(int[] arr, int start, int end, CountObject count){
int pivot = arr[start];
count.increaseCount();
//checks if left pointer < pivot
for(int i=end; i>start; i--){
if(arr[i]>pivot){
int temp= arr[end];
arr[end]=arr[i];
arr[i]=temp;
end--;
}
}
int temp = arr[start];//=pivot
arr[start] = arr[end];
arr[end] = temp;
return end;
}
}
I'm using a CountObject class to count. It contains a method increaseCount and an instance variable count.
So I finally figured it out. I had to use another technique to traverse through the list. In my OP I used the first element as pivot and compared it with all the elements beginnign from the end of the list. Now I start with the 2nd element of the list / the current sublist.
Here is the Code that solved my problem, I hope this will spare someone 2 days of work though it was educational for me to do it myself.
import java.util.Scanner;
public class Quickie {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int temp;
int size = sc.nextInt();
int[] list = new int[size];
for (int i = 0; i < size; i++) {
temp = sc.nextInt();
list[i] = temp;
}
int end = size - 1;
CounterClass count = new CounterClass(0);
quickSort(list, 0, end, count);
int firstElement = list[0];
int lastElement = list[size - 1];
System.out.println("Number of pivots: " + count.getCount());
System.out.println("First Element: " + firstElement);
System.out.println("Last Element: " + lastElement);
}
private static void quickSort (int []arr, int start, int end, CounterClass count){
int partition = partition(arr, start, end, count);
if (partition-1>start){
quickSort(arr, start, partition-1,count);
}
if (partition+1<end){
quickSort(arr, partition+1,end,count);
}
}
private static int partition (int[]arr, int start, int end, CounterClass count){
int pivot = arr[start];
count.count++;
int pointer = start+1;
int i =pointer;
for (int j=pointer; j<=end;j++){
if (arr[j]<pivot){
int temp = arr[j];
arr[j]=arr[i];
arr[i]=temp;
i++;
}
}
i-=1;
int temp=arr[start];
arr[start]=arr[i];
arr[i]=temp;
return (i);
}
}
class CounterClass{
int count;
public CounterClass(int count){
this.count = count;
}
public int getCount() {
return count;
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am following the following pseudocode:
function quicksort(array)
if length(array) > 1
pivot := select any element of array
left := first index of array
right := last index of array
while left ≤ right
while array[left] < pivot
left := left + 1
while array[right] > pivot
right := right - 1
if left ≤ right
swap array[left] with array[right]
left := left + 1
right := right - 1
quicksort(array from first index to right)
quicksort(array from left to last index)
but when I try to implement it in java, I insert code:
import java.util.Arrays;
public class ALGQuickSort {
public static void main(String[] args) {
int[] array = {6, 3, 4, 8, 9, 10, 1};
quickSort(array);
System.out.println(Arrays.toString(array));
}
public static void quickSort(int[] array) {
int pivot = array[array.length - 1];
if (array.length > 1) {
int left = 0;
int right = array.length - 1;
while (left <= right) {
while (array[left] < pivot) {
left++;
}
while (array[right] > pivot) {
right--;
}
if (left <= right) {
swap(array[left], array[right]);
right--;
left++;
}
int[] array1 = Arrays.copyOfRange(array, 0, right);
int[] array2 = Arrays.copyOfRange(array, left, array.length - 1);
quickSort(array1);
quickSort(array2);
}
}
}
public static void swap(int a, int b) {
int aux = a;
a = b;
b = aux;
}
}
the system shows me the following error on the screen:
Exception in thread "main" java.lang.IllegalArgumentException: 5 > 4
at java.util.Arrays.copyOfRange(Arrays.java:3591) at
alg.quicksort.ALGQuickSort.quickSort(ALGQuickSort.java:43) at
alg.quicksort.ALGQuickSort.quickSort(ALGQuickSort.java:44) at
alg.quicksort.ALGQuickSort.main(ALGQuickSort.java:21)
C:\Users\Alex\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53:
Java returned: 1
the error is in the line:
int[] array2 = Arrays.copyOfRange(array, left, array.length - 1);
someone can help me pls?
Improvements/corrections to your quick-sort algorithm:
Correct your swap method: The swap method that you are using will not work.
The recursive call should be outside the for loop: Your pseudo-code is correct, but in your implementation it is not the case.
Place the Pivot at its correct position and then have a recursive call on sub-arrays that now (for-sure) should not contain the pivot element. After the while loop, you are sure that right+1 == left (think on it a bit and you will understand why this is true). Now swap the array[left] with pivot element and give a recursive call on 2 different sub-arrays (left sub-array to the pivot is beginIndex..right and right sub-array to the pivot is left+1..endIndex where I assume that you need to sort array[beginIndex..endIndex])
Avoid copying: Its better to avoid copying a part of the array (instead you can pass the startIndex and the endIndex to denote the sub-array you want to sort)
Use Randomized Quick sort: It would also be better if you don't always select the last element as your pivot (what you can do here is just before starting to sort select any random element and then swap it with the last element of your array. Using this strategy you don't have to make much changes in your existing code) This selection of random element as pivot is much better. See this link for more details.
Make swap method private: Not relevant to the algorithm, but it is good if you make the swap method private as you might not intend to call it from outside of this class.
If you intend to swap the elements of array with index say index1 and index2, then the following code will work:
public static void swap(int[] array, int index1, int index2) {
int aux = array[index1];
array[index1] = array[index2];
array[index2] = aux;
}
The following is the final code with all the above suggested changes:
public static void main(String[] args) {
int[] array = {6, 30, 7, 23, 4, 8, 9, 10, 1, 90};
quickSort(array, 0, array.length - 1);
System.out.println(Arrays.toString(array));
}
public static void quickSort(int[] array, int beginIndex, int endIndex) {
// System.out.println("called quick sort on the following : " + beginIndex + " " + endIndex);
int arrayLength = endIndex - beginIndex + 1;
int pivot = array[endIndex];
if (arrayLength > 1) {
int left = beginIndex;
int right = endIndex - 1;
while (left <= right) {
// System.out.println(left + " " + right);
while (left <= endIndex && array[left] < pivot) {
left++;
}
while (right >= beginIndex && array[right] > pivot) {
right--;
}
if (left <= right) {
swap(array, left, right);
right--;
left++;
}
}
swap(array, left, endIndex); // this is crucial, and you missed it
if (beginIndex < right) {
quickSort(array, beginIndex, right);
}
if (left + 1 < endIndex) {
quickSort(array, left + 1, endIndex);
}
}
}
private static void swap(int[] array, int index1, int index2) {
int aux = array[index1];
array[index1] = array[index2];
array[index2] = aux;
}
Firstly, the two lines
int[] array1 = Arrays.copyOfRange(array, 0, right);
int[] array2 = Arrays.copyOfRange(array, left, array.length - 1);
are wrong. You must not copy the arrays. This will prevent the Quicksort algorithm from working since you sort the temporary copies in your recursive calls. The sorted sub arrays will be discarded afterwards.
Another bug in your program raises the exception: the third parameter of Arrays.copyOfRange is exclusive. I.e. it will not copy elements from to to but from to to - 1. But you already subtracted one from the upper bound, and in Quicksort it might happen that one of the sub arrays has zero size. In this case the range to copy becomes negative. That's the exception.
There is a third bug: you swapped the first two lines of the pseudo code. This will crash on empty arrays.
Finally, you cannot implement the Quicksort algorithm in this way as shown in the pseudo code because Java (unlike e.g. C) does not support array slices.
You need to modify the algorithm in a way that you split it into two methods:
One method to recursively sort an array slice:
Note that I replaced the array start and end by from and to.
public static void quickSort(int[] array, int from, int to) {
if (array.length <= 1)
return;
int pivot = array[to];
int left = from;
int right = to;
while (left <= right) {
while (array[left] < pivot)
left++;
while (array[right] > pivot)
right--;
if (left <= right) {
swap(array[left], array[right]);
right--;
left++;
}
quickSort(array, from, right);
quickSort(array, left, to);
}
}
And a second method to sort an entire array that calls the above one for the entire array.
public static void quickSort(int[] array) {
return quickSort(array, 0, array.length - 1);
}
I am trying to write code to determine the n smallest item in an array. It's sad that I am struggling with this. Based on the algorithm from my college textbook from back in the day, this looks to be correct. However, obviously I am doing something wrong as it gives me a stack overflow exception.
My approach is:
Set the pivot to be at start + (end-start) / 2 (rather than start+end/2 to prevent overflow)
Use the integer at this location to be the pivot that I compare everything to
Iterate and swap everything around this pivot so things are sorted (sorted relative to the pivot)
If n == pivot, then I think I am done
Otherwise, if I want the 4 smallest element and pivot is 3, for example, then I need to look on the right side (or left side if I wanted the 2nd smallest element).
-
public static void main(String[] args) {
int[] elements = {30, 50, 20, 10};
quickSelect(elements, 3);
}
private static int quickSelect(int[] elements2, int k) {
return quickSelect(elements2, k, 0, elements2.length - 1);
}
private static int quickSelect(int[] elements, int k, int start, int end) {
int pivot = start + (end - start) / 2;
int midpoint = elements[pivot];
int i = start, j = end;
while (i < j) {
while (elements[i] < midpoint) {
i++;
}
while (elements[j] > midpoint) {
j--;
}
if (i <= j) {
int temp = elements[i];
elements[i] = elements[j];
elements[j] = temp;
i++;
j--;
}
}
// Guessing something's wrong here
if (k == pivot) {
System.out.println(elements[pivot]);
return pivot;
} else if (k < pivot) {
return quickSelect(elements, k, start, pivot - 1);
} else {
return quickSelect(elements, k, pivot + 1, end);
}
}
Edit: Please at least bother commenting why if you're going to downvote a valid question.
This won't fix the issue, but there are several problems with your code :
If you do not check for i < end and j > start in your whiles, you may run into out of bounds in some cases
You choose your pivot to be in the middle of the subarray, but nothing proves that it won't change position during partitioning. Then, you check for k == pivot with the old pivot position, which obviously won't work
Hope this helps a bit.
Alright so the first thing I did was rework how I get my pivot/partition point. The shortcoming, as T. Claverie pointed out, is that the pivot I am using isn't technically the pivot since the element's position changes during the partitioning phase.
I actually rewrote the partitioning code into its own method as below. This is slightly different.
I choose the first element (at start) as the pivot, and I create a "section" in front of this with items less than this pivot. Then, I swap the pivot's value with the last item in the section of values < the pivot. I return that final index as the point of the pivot.
This can be cleaned up more (create separate swap method).
private static int getPivot(int[] elements, int start, int end) {
int pivot = start;
int lessThan = start;
for (int i = start; i <= end; i++) {
int currentElement = elements[i];
if (currentElement < elements[pivot]) {
lessThan++;
int tmp = elements[lessThan];
elements[lessThan] = elements[i];
elements[i] = tmp;
}
}
int tmp = elements[lessThan];
elements[lessThan] = elements[pivot];
elements[pivot] = tmp;
return lessThan;
}
Here's the routine that's calls this:
private static int quickSelect(int[] elements, int k, int start, int end) {
int pivot = getPivot(elements, start, end);
if (k == (pivot - start + 1)) {
System.out.println(elements[pivot]);
return pivot;
} else if (k < (pivot - start + 1)) {
return quickSelect(elements, k, start, pivot - 1);
} else {
return quickSelect(elements, k - (pivot - start + 1), pivot + 1, end);
}
}
I have written this code but it will print these stack traces in the console please help me thanks! (Aslo "p" and "q" are the first and last index of our array ,respectively)
public class JavaQuickSort {
public static void QuickSort(int A[], int p, int q) {
int i, last = 0;
Random rand = new Random();
if (q < 1) {
return;
}
**swap(A, p, rand.nextInt() % (q+1));**
for (i = p + 1; i <= q; i++) {
if (A[i] < A[p]) {
swap(A, ++last, i);
}
}
swap(A, p, last);
QuickSort(A, p, last - 1);
QuickSort(A, last + 1, q);
}
private static void swap(int[] A, int i, int j) {
int temp;
temp = A[i];
**A[i] = A[j];**
A[j] = temp;
}
public static void main(String[] args){
int[] A = {2,5,7,3,9,0,1,6,8};
**QuickSort(A, 0,8 );**
System.out.println(Arrays.toString(A));
}
}
the Stack traces :
run:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -3
at JavaQuickSort.swap(JavaQuickSort.java:38)
at JavaQuickSort.QuickSort(JavaQuickSort.java:22)
at JavaQuickSort.main(JavaQuickSort.java:45)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)
I also bold those statements that cause these stack traces. like ==> ** ...**
EDITED:
public class JavaQuickSort {
public static void QuickSort(int arr[],int lo,int hi) {
int n = arr.length;
if(n<=1)
return;
**int r = partition(arr);**
**QuickSort(arr,lo , r-1);**
QuickSort(arr, r+1, hi);
}
private static void swap(int[] A, int i, int j) {
int temp;
temp = A[i];
**A[i] = A[j];**
A[j] = temp;
}
public static int partition(int arr[]){
int i, last = 0;
Random rand = new Random();
int n = arr.length;
if (n <= 1)
return arr[0];
**swap(arr, 0, rand.nextInt(n));**
for (i =1; i <n; i++) {
if (arr[i] < arr[0]) {
swap(arr, ++last, i);
}
}
swap(arr, 0, last);
return last;
}
public static void main(String[] args){
int[] A = {2,5,7,3,9,0,1,6,8};
**QuickSort(A, 0,8 );**
System.out.println(Arrays.toString(A));
}
}
I have edited my post for being more understandable also it will print these stack traces and I bold the lines that cause these stack traces!!!
the stack traces :
run:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at JavaQuickSort.swap(JavaQuickSort.java:27)
at JavaQuickSort.partition(JavaQuickSort.java:39)
at JavaQuickSort.QuickSort(JavaQuickSort.java:19)
at JavaQuickSort.QuickSort(JavaQuickSort.java:20)
at JavaQuickSort.QuickSort(JavaQuickSort.java:20)
at JavaQuickSort.QuickSort(JavaQuickSort.java:20)
at JavaQuickSort.QuickSort(JavaQuickSort.java:20)
at JavaQuickSort.main(JavaQuickSort.java:52)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)
please help me thanks
EDITED :
I have written this code with paying attention to the forst answer of this post but it wont sort my array!!!
public class JavaQuickSort {
public static void QuickSort(int arr[], int lo, int hi) {
if (hi > lo) {
Random rand = new Random();
int pivotIndex = lo + rand.nextInt(hi-lo+1);
int pivotnewIndex = partition(arr, lo, hi,pivotIndex);
QuickSort(arr, lo, pivotnewIndex - 1);
QuickSort(arr, pivotnewIndex + 1, hi);
}
}
private static void swap(int[] A, int i, int j) {
int temp;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
public static int partition(int arr[],int lo,int hi,int pivotIndex)
{
int pivotValue = arr[pivotIndex];
swap(arr, hi, pivotIndex);
int storeIndex = lo;
for(int i = lo;i<hi;i++){
if (arr[i]<=pivotValue)
swap(arr, storeIndex, i);
storeIndex = storeIndex ++;
}
swap(arr, storeIndex, hi);
return storeIndex;
}
public static void main(String[] args) {
int[] A = {2, 5, 7, 3, 9, 0, 1, 6, 8};
QuickSort(A, 0, 8);
System.out.println(Arrays.toString(A));
}
}
the output:
run:
[2, 9, 3, 8, 0, 6, 7, 1, 5]
BUILD SUCCESSFUL (total time: 2 seconds)
I need your help really I confused !!!
Some problems with your code are:
Don't create a new Random instance for one time uses. Just create it once, store it in say a static field, and then use it to generate many random numbers for your application.
When creating a random index for the pivot, it must lie between p and q inclusive.
Use Random.nextInt(int n) overload to generate a random number in a given range
Perhaps use lo and hi instead of p and q, and int[] arr instead of int A[]
You can get the length of an array with its .length member
As for the quicksort algoritm itself, it doesn't look like anything I've seen before. I recommend studying the standard imperative implementation and adapting that.
See also
Wikipedia/Quicksort
Update
Unfortunately you have mixed up the pseudocodes from Wikipedia somewhat. You want to adapt this algorithm:
function partition(array, left, right, pivotIndex)
pivotValue := array[pivotIndex]
swap array[pivotIndex] and array[right] // Move pivot to end
storeIndex := left
for i from left to right - 1 // left ≤ i < right
if array[i] ≤ pivotValue
swap array[i] and array[storeIndex]
storeIndex := storeIndex + 1
swap array[storeIndex] and array[right] // Move pivot to its final place
return storeIndex
procedure quicksort(array, left, right)
if right > left
select a pivot index //(e.g. pivotIndex := left+(right-left)/2)
pivotNewIndex := partition(array, left, right, pivotIndex)
quicksort(array, left, pivotNewIndex - 1)
quicksort(array, pivotNewIndex + 1, right)
Note that the above algorithm selects the middle element of the subarray between left and right for the pivot index. Since you want a randomized quicksort, you want to choose a random index between left and right inclusive, so the formula needs to be changed as follows:
pivotIndex := left + (random number between 0 and right-left inclusive)
So, for example, if left = 5 and right = 7, then you want pivotIndex to be 5 + x where x is a random number between 0 and 7-5=2 inclusive.
Since Random.nextInt(n) has an exclusive upper bound, translating this to Java would be something like:
int pivotIndex = lo + rand.nextInt(hi - lo + 1);
Final correction
You've made a common mistake for beginners here:
// HORRIBLE FORMATTING! Don't do this!
if (arr[i]<=pivotValue)
swap(arr, storeIndex, i);
storeIndex = storeIndex ++;
If you noticed the pseudocode above, both statements are supposed to be part of the if body, but the above code, when properly indented and with braces added, is really this:
// PROPER FORMATTING! Reveals bug instantly!
if (arr[i]<=pivotValue) {
swap(arr, storeIndex, i);
}
storeIndex = storeIndex ++;
The fix, therefore is to move the storeIndex increment to the if body like this:
// Corrected according to pseudocode!
if (arr[i]<=pivotValue) {
swap(arr, storeIndex, i);
storeIndex = storeIndex ++;
}
Or you can also just do:
// Nice and clear!
if (arr[i]<=pivotValue) {
swap(arr, storeIndex++, i);
}
The lessons from this latest update is:
Always indent your code properly
A good IDE can make this a breeze, you really have no excuse
Make a habit of putting braces on if statements, even when they're not strictly necessary
Many subtle bugs are due to omission of braces
Use post/pre-increments sensibly
Like many things, they can be abused beyond comprehension, but used appropriately and idiomatically they lead to concise and readable code
One last thing
When I mentioned .length of arrays, I meant that instead of this:
int[] A = {2, 5, 7, 3, 9, 0, 1, 6, 8};
QuickSort(A, 0, 8); // BAD! Don't hardcode array length!
You should do this:
int[] arr = {2, 5, 7, 3, 9, 0, 1, 6, 8};
QuickSort(arr, 0, arr.length - 1); // GOOD!
The random generator produces positive and negative values. That's why eventually you call swap with a negative q value.
swap(A, p, rand.nextInt() % (q+1));
The random integer generated may be below p, clearly you would want it to be something between p and q.
As this is not homework, and I'd take the homework category to encompass self-learning, you should just use the standard Arrays.sort(int[]).