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