递归分区排序是行为无效的

时间:2015-01-05 06:41:02

标签: java sorting quicksort

我为分区排序编写了一个递归方法来对数组进行排序,但是当我使用超过10-20个元素的数组时,程序需要很长时间才能完成(在我的计算机上有一个100,000个int的冒泡类型)数组大约需要15-20秒,但只有30个整数的数组,我的分区排序大约需要45秒进行排序。

这是代码。

public static int[] partitionSortRecursive(int[] array, int beginning, int end)
{
    if (end < beginning)
        return array;

    int pivot = (array[beginning] + array[end]) / 2;
    int firstUnknown = beginning;
    int lastS1 = beginning - 1;
    int firstS3 = end + 1;


    while (firstUnknown < firstS3)
    {
        if (array[firstUnknown] == pivot)
        {
            firstUnknown++;
        }
        else if (array[firstUnknown] > pivot)
        {
            firstS3--;
            int temp = array[firstUnknown];
            array[firstUnknown] = array[firstS3];
            array[firstS3] = temp;
        }
        else
        {
            lastS1++;
            int temp = array[firstUnknown];
            array[firstUnknown] = array[lastS1];
            array[lastS1] = temp;
            firstUnknown++;
        }

    }

    partitionSortRecursive(array, 0, lastS1);
    partitionSortRecursive(array, firstS3, end);

    return array;
}

2 个答案:

答案 0 :(得分:3)

您没有使用正确的枢轴元素。您可以计算左右值的平均值,但您必须将子数组中的样本值改为分区。

您可以选择最右边,中心或任何其他元素。所以你的第一行代码应该是这样的

int pivot = array[(beginning + end) / 2];
// or
int pivot = array[end];

你也可以采取任何其他元素(例如随机)

编辑:这不能解决性能问题。

据我所知,快速排序会将数组划分为两个子数组A和B,其中A中的所有元素都小于B中的任何元素,然后对两个子数组执行相同的操作。

所以基本的调用结构应该是这样的

void DoSort (array, i, j)
{
  pivot = Partition (array, i, j)
  DoSort (array, i,pivot)
  DoSort (array, pivot + 1, j)
}

你的实施基本上是

void DoSort (array, i, j)
{
  pivot = Partition (array, i, j)
  DoSort (array, 0, pivot)     // <<<<<< notice the '0' instead of 'i'
  DoSort (array, pivot + 1, j)
}

所以你总是从最初的数组开始,这很可能需要一段时间

答案 1 :(得分:0)

而不是像这样的直接反复调用

partitionSortRecursive(array, 0, lastS1);
partitionSortRecursive(array, firstS3, end);

组织内部堆栈,您可以在其中保存索引对。当堆栈不为空时,从堆栈中获取下一对。在函数结束时,不要调用相同的函数,但在堆栈中放入2对(0, lastS1)(firstS3, end)