Java 插入排序完成的快速排序-哪里出了问题?

Java 插入排序完成的快速排序-哪里出了问题?,java,performance,sorting,overflow,Java,Performance,Sorting,Overflow,我正在为一个班级做一个项目。我们将编写一个快速排序,以指定的值转换为插入排序。这没问题,我现在遇到的困难是弄清楚为什么我没有得到我期望的表现 其中一个要求是,它必须在1300毫秒内对50万整数的数组进行排序(这是在标准机器上,所以CPU速度不是问题)。首先,由于堆栈溢出错误(太多递归调用…),我无法让它在5000000上工作。如果我增加堆的大小,我仍然会比这个慢很多 下面是代码。有任何提示吗 提前谢谢 public class MyQuickSort { public static v

我正在为一个班级做一个项目。我们将编写一个快速排序,以指定的值转换为插入排序。这没问题,我现在遇到的困难是弄清楚为什么我没有得到我期望的表现

其中一个要求是,它必须在1300毫秒内对50万整数的数组进行排序(这是在标准机器上,所以CPU速度不是问题)。首先,由于堆栈溢出错误(太多递归调用…),我无法让它在5000000上工作。如果我增加堆的大小,我仍然会比这个慢很多

下面是代码。有任何提示吗

提前谢谢

public class MyQuickSort {

    public static void sort(int [] toSort, int moveToInsertion)
    {
        sort(toSort, 0, toSort.length - 1, moveToInsertion);
    }

    private static void sort(int[] toSort, int first, int last, int moveToInsertion)
    {
        if (first < last)
        {
            if ((last - first) < moveToInsertion)
            {
                insertionSort(toSort, first, last);
            }
            else
            {
                int split = quickHelper(toSort, first, last);
                sort(toSort, first, split - 1, moveToInsertion);
                sort(toSort, split + 1, last, moveToInsertion);
            }
        }
    }

    private static int quickHelper(int[] toSort, int first, int last)
    {
        sortPivot(toSort, first, last);
        swap(toSort, first, first + (last - first)/2);
        int left = first;
        int right = last;
        int pivotVal = toSort[first];
        do
        {
            while ( (left < last) && (toSort[left] <= pivotVal)) 
            {
                left++;
            }

            while (toSort[right] > pivotVal) 
            {
                right--;
            }

            if (left < right) 
            { 
                swap(toSort, left, right); 
            }

        } while (left < right);

        swap(toSort, first, right);


        return right;
    }

    private static void sortPivot(int[] toSort, int first, int last)
    {
        int middle = first + (last - first)/2;

        if (toSort[middle] < toSort[first]) swap(toSort, first, middle);

        if (toSort[last] < toSort[middle]) swap(toSort, middle, last);

        if (toSort[middle] < toSort[first]) swap(toSort, first, middle);

    }

    private static void insertionSort(int [] toSort, int first, int last)
    {
         for (int nextVal = first + 1; nextVal <= last; nextVal++)
            {
                int toInsert = toSort[nextVal];
                int j = nextVal - 1;
                while (j >= 0 && toInsert < toSort[j])
                {
                    toSort[j + 1] = toSort[j];
                    j--;
                }
                toSort[j + 1] = toInsert;
            }
    }

    private static void swap(int[] toSort, int i, int j)
    {
        int temp = toSort[i];
        toSort[i] = toSort[j];
        toSort[j] = temp;
    }

}
公共类MyQuickSort{
公共静态无效排序(int[]toSort,int moveToInsertion)
{
排序(toSort,0,toSort.length-1,moveToInsertion);
}
私有静态无效排序(int[]toSort、int first、int last、int moveToInsertion)
{
如果(第一次<最后一次)
{
如果((最后一个-第一个)
当输入数组较大时,递归函数自然会遇到堆栈溢出问题。这就是您尝试使用上述代码时出现的情况。我建议您使用自己的堆栈编写迭代快速排序。它应该很快,因为在运行时没有进行堆栈帧分配/释放我。您也不会遇到堆栈溢出问题。性能还取决于您运行插入排序的时间点。我没有特定的输入大小,插入排序与快速排序相比性能较差。我建议您尝试使用不同的大小,我相信您会注意到这一差异

您可能还想在插入排序中使用二进制搜索来提高性能。我不知道当您在较小的输入上运行时,它能提高多少,但这是一个很好的技巧


<>我不想共享代码,因为这并不能让你学会如何将递归Quasd排序转换成迭代的一个。如果你在转换到迭代的时候遇到问题,请告诉我。

< P>我没有用你的算法测试过,我不知道你在用什么样的数据集,但是考虑选择一个比最左边的E更好的枢轴。从维基百科的快速排序:

在早期版本中选择pivot 的最左边的元素 分区通常会被选为 轴心元素。不幸的是 已在上导致最坏情况行为 排序数组,这是一个相当复杂的问题 常见用例。问题是 通过选择一个 轴的随机索引,选择 分区的中间索引或 (特别是对于较长的分区) 选择第一个的中间值, 中间和最后一个元素 轴心分区

我明白了

实际上,根本不是我的排序错误。我生成的数字范围在0-100之间(用于测试以确保它被排序)。这导致了大量的重复,这意味着许多分区都存在重复。将范围更改为min_int和max_int使它运行得更快


不过谢谢你的帮助:D

这是什么课程?高中/大学?我很好奇,大学二年级,所以我不认为这有什么复杂的…我想我可能只是有一个小错误…只是看了一下Java实现,当元素数小于7时,他们会返回insertionsort。子数组的大小我们移到插入sort@Srikanth-从递归到迭代的转换对此人没有帮助。大数据集只会生成OutOfMemoryError。这里的二进制插入排序是个坏主意…二进制插入排序在大于100个元素的数组上只比标准插入排序快(数字可能不同),但在这里,插入排序用于在元素数小于10-12时加快速度。@阿米尔:当然,如果输入足够大,任何给定的解决方案都可能遇到OutOfMemoryError。从递归转换为迭代会增加程序可以处理的输入大小。函数cal st占用的空间ack显然比迭代版本中使用的堆栈要多