To me, it just seems much less intuitive to write the functions like those above. Take this sample code that I just wrote (and tested) as an example, and see if you can understand it and use it to help you through your code. NB: This is slightly different than yours in that it picks a pivot at random.
void quicksort(int[] nums)
{
if (nums.length > 1)
{
quicksort(nums, 0, nums.length);
}
}
//[left,right)
private void quicksort(int[] nums, int left, int right)
{
if (left < right - 1)
{
int position = left;
int pivot = pickPivot(left, right);
if (pivot != right - 1)
swap(nums, pivot, right-1);
for (int i = left; i < right - 1; i++)
{
if (nums[i] <= nums[right-1])
{
swap(nums, position, i);
position++;
}
}
swap(nums, position, right-1);
quicksort(nums, left, position);
quicksort(nums, position + 1, right);
}
}
//[left,right)
private int pickPivot(int left, int right)
{
return rand.nextInt(right-left) + left; // rand is a Random object
}
private void swap(int[] nums, int start, int end)
{
int temp = nums[end];
nums[end] = nums[start];
nums[start] = temp;
}
As others have said, it can be difficult to debug recursive functions. If you can't figure it out from here, I suggest using a debugger. Eclipse's debugger is pretty easy to use and very helpful. This may be frustrating and difficult to figure out, but the process is one that every programmer (should and) has to go through.
Once you think you have it figured out, use a testing function similar to this one to test it out (I would initially start off with a smaller size in case there are errors, this way it will be easier to debug):
void testQuickSort()
{
for(int i = 0; i < 1000; i++)
{
int size = rand.nextInt(100)+1;
int[] nums = new int[size];
for (int j = 0; j < size; j++)
{
nums[j] = rand.nextInt(10);
if (rand.nextBoolean())
{
nums[j] *= -1;
}
}
quicksort(nums);
assert sorted(nums) == true;
}
}
private boolean sorted(int[] array)
{
for (int i = 0; i < array.length-1; i++)
{
if (array[i] > array[i+1])
return false;
}
return true;
}