Ah ha. I think you/ve been here http://www.sorting-algorithms.com/static/QuicksortIsOptimal.pdf
You made an error transcribing the code. It should be
int i = l - 1;
when you initialise i. This means you don't examine the leftmost element in the partition.
Also, that paper has different conditions in your for loops
for (k = 1; k < p; k++, j--)
and
for (k = r-1; k > q; k--, i++)
EDIT:
You also made a couple of other errors where you had the digit 1 where it should have been the letter l.
Finally, the two statements below were
int v = a[r];
if (r<=l) return;
but if you do this you get an index error as the access comes before the test. Fixing these, renaming variables to something more meaningful and commenting extensively, one gets:
public class quick3 {
public static void quicksort3(int a[],int left,int right){
int k;
if (right<=left) return;
int pivot_value = a[right];
int current_left_index = left-1;
int current_right_index = right;
int left_equal_key_index = left-1;
int right_equal_key_index = right;
for (;;) {
// skip past elements from the left with keys less than the pivot_value (i.e, already at the correct side)
// must terminate because pivot_value is at index'right'
while (a[++current_left_index]<pivot_value)
;
while (pivot_value<a[--current_right_index])
if (current_right_index==left) break; // terminate if we reach the beginning.
// if we meet in the middle, everything is now partitioned, so bail for cleanup
// note this is true if we broke out of the previous while.
if (current_left_index>=current_right_index) break;
// current_left_index points at bigger than pivot_value.
// current_right_index points at something smaller than pivot_value, both are in the wrong side.
// So swap them
swap( a,current_left_index, current_right_index);
// if we stopped (after skipping over stuff) at something equal to pivot_value, swap it with the first element at the beginning whose value is not 'pivot_value'
// and increment our index to the end of the elements with keys equal to pivot_value that we've stored there
if (a[current_left_index]==pivot_value) {
left_equal_key_index++;
swap(a,left_equal_key_index,current_left_index);
}
// and again, except move it to the end
if (pivot_value==a[current_right_index]) {
right_equal_key_index--;
swap( a,right_equal_key_index,current_right_index);
}
}
// after the for loop terminates...
//the rigtmost element has value 'pivot_value'
// all the keys of elements between left and left_equal_key_index are equal to pivot_value (there may be none of these)
// all the keys of elements between right_equal_key_index and right are equal to pivot_value (there's at least one - the key value of the rightmost element is 'pivot_value'
// All the keys after left_equal_key_index and before current_left_index are less than 'pivot_value'.
// All the keys after current_right_index and before right_equal_key_index are greater than 'pivot_value'.
// swap 'pivot_value' with whatever we're stlll pointing at to put it in the right place
swap(a,current_left_index,right);
current_right_index = current_left_index-1; // i.e. just to the left of 'pivot_value'
current_left_index = current_left_index+1; // i.e. just to the right of 'pivot_value'
// move all those elements with key value equal to 'pivot_value' from the beginning next to the pivot_value we just moved
for (k = left; k < left_equal_key_index; k++, current_right_index--)
swap(a,k,current_right_index);
// and from the end to next to pivot_value
// right - 1 because we already moved the pivot_value value
for (k = right-1; k > right_equal_key_index; k--, current_left_index ++)
swap(a,k,current_left_index);
// now all keys equal to pivot_value are adjacent in the middle. current_left_index and current_right_index are positioned to the right (and left)
// respectively of those, since we don't need to sort these in recursive calls
quicksort3(a,left,current_right_index);
quicksort3(a,current_left_index,right);
}
public static void main(String[]args){
int a[]=new int[]{4,6,5,9,7,8,3};
quicksort3(a,0,a.length-1);
for (int l=0;l<a.length;l++){
System.out.println(a[l]);
}
}
public static void swap(int a[],int l,int r) {
int t=a[l];
a[l]=a[r];
a[r]=t;
}
... which appears to work. I still maintain you'd have got more value from debugging it yourself.
(Although the original authors who used both 1 and l - and apparently a language that doesn't give out-of-range index errors) need chastising too)