我必须测量快速排序和合并排序所需的时间,以便用随机数对文件中的整数进行排序。
我在网上读到,对于大量数据,合并排序应该比快速排序快,但我的测量结果却恰恰相反,合并排序所需的时间几乎是快速排序所需时间的两倍。
我对这些算法的实现是个问题吗?
测量结果:
快速排序:
内景:500万-715194000 ns
1000万内景-1383187400南纬
5000万内景-6819586800纳士
1亿内景-14159986000纳士
1.5亿内景-22431202200纳秒
合并排序:
内景:500万-1644349000 ns
内景1000万-2186410800纳士
5000万内景-14427917500纳秒
1亿内景-26487337400纳秒
1.5亿内景-42229109700南纬
//Quick Sort Implementation
public static void quickSort(int[] a, int start, int end){
if(end - start < 2){
return;
}
int pivtIndex = partition(a, start, end);
quickSort(a, start, pivtIndex);
quickSort(a, pivtIndex + 1, end);
}
public static int partition(int[] a, int start, int end){
int pivot = a[start];
int i = start;
int j = end;
while(i < j){
while(i < j && a[--j] >= pivot);
if(i < j){
a[i] = a[j];
}
while(i < j && a[++i] <= pivot);
if(i < j){
a[j] = a[i];
}
}
a[j] = pivot;
return j;
}
//Merge Sort Implementation
public static void mergeSort(int[] input, int start, int end){
if(end - start < 2){
return;
}
int mid = (start + end)/2;
mergeSort(input, start, mid);
mergeSort(input, mid, end);
merge(input, start, mid, end);
}
public static void merge(int[] input, int start, int mid, int end){
if(input[mid-1] <= input[mid]){
return;
}
int i = start, j = mid, tempIndex = 0;
int[] temp = new int[end - start];
while(i < mid && j < end){
temp[tempIndex++] = input[i] <= input[j] ? input[i++] : input[j++];
}
System.arraycopy(input, i, input, start + tempIndex, mid - i);
System.arraycopy(temp, 0, input, start, tempIndex);
}
2条答案
按热度按时间vtwuwzda1#
我认为,尽管数组的大小在15010^6的范围内,但快速排序肯定有优势,原因如下:
假设java中整数的大小为4字节,
((15010^6*4字节)/1024字节)/1024兆字节)~572 mb。
三级缓存的大小约为50MB。
因此,(572-50)~522MB内存必须与主存一起使用(不包括l1和l2,因为它们的大小相对较低)。
现在,对于额外的522MB,合并排序必须借助主内存。
因此,合并排序显然还必须使用辅助阵列所需的主内存。
访问主存是一项繁重的操作,合并排序需要比快速排序更多地访问主存,因为它的附属阵列。
2o7dmzc52#
在理想世界或真正的随机数字列表中,快速排序应该是最好的,但是当数据出现错误时,会出现一些问题。
这看起来像是原始文件的很好的实现。我假设你已经检查了整数的排序是否正确。
当您选择第一个元素作为轴心时,应该检查的一些角点情况是o(n^2)。
已排序,因为您选择第一个元素作为轴。
风琴管1,2,3,2,1也会导致行为不端。
如果以最后一个元素为轴心,则进行反向排序
少数uniques,尝试一个只有0,1的模式
差一点把几个放错地方的号码整理好了。
对于合并排序,您需要检查(开始+结束)是否不会导致整数溢出。
在合并排序中,您还可以通过智能交换分配进行优化,这样您只需要分配一次。
当子数组的长度低于某个阈值(通常在11-32之间)时,这两种算法都可以通过插入排序进行优化。