繁体   English   中英

使用快速排序算法进行Java排序

[英]Java sorting with quicksort algorithm

我正在尝试在java中编写quicksort程序。这是我的分区函数

int partition(int[] array, int start, int end) 
{
    int last = end - 1;
    int first = start;
    int pivot = array[start];
    while (first < last)
    {
        while (first < last && pivot <= array[last])
            last = last - 1;
        array[first] = array[last];
        while (first < last && pivot > array[first])
            first = first + 1;
        array[last] = array[first];
    }
    array[first] = pivot;
    return first;
}

那是我的快速排序功能

void quickSort(int array[], int start, int end) {
      int index = partition(array, start, end);
      if (start < index - 1)
            quickSort(array, start, end - 1);
      if (index < end)
            quickSort(array, index, end);}

但是,当我在Junit中测试代码时,它给了我错误。 我需要更改quickSort或分区功能。 我该怎么办。

这里:

 if (start < index - 1)
                quickSort(array, start, end - 1);

为什么要从开始到结束1的较低分区调用quickSort? 不应该是:

  if (start < index - 1)
                    quickSort(array, start, index - 1);

上部是从索引+1到结束。

此外,最好在分区之前检查这样的限制并删除if语句:

 if (end <= start) { return; }

对我来说,编写上述功能似乎不太直观。 以我刚刚编写(和测试)的此示例代码为例,看看您是否可以理解并使用它来帮助您完成代码。 注意:这与您的稍有不同,因为它随机选择了一个轴心。

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;
}

正如其他人所说,调试递归函数可能很困难。 如果您不能从这里弄清楚,建议使用调试器。 Eclipse的调试器非常易于使用并且非常有用。 这可能令人沮丧并且很难弄清,但是这个过程是每个程序员(应该也是)必须经历的过程。

一旦您确定了答案,请使用与此功能类似的测试功能进行测试(如果有错误,我会先从较小的size开始,这样可以更轻松地进行调试):

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;
}

行“ quickSort(数组,索引,结尾)”上的堆栈溢出错误;

当数组足够大时,调用会多次调用同一函数溢出堆栈。

代替递归,将索引对放在堆栈中,并为顶部对调用quickSort()。

void quickSort(int array[], int start, int end) {
  int index = partition(array, start, end);
  if (start < index - 1)
//        quickSort(array, start, end - 1);
        push(start, end - 1);
  if (index < end)
//        quickSort(array, index, end);}
        push(index, end);

while(stack is not empty) {
    //get next pair and call quickSort
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM