关于快速排序和归并排序的速度问题

问题描述

关于快速排序和归并排序的速度问题

#include
#include
#include
void mergerarray(int* src,int* tem,int start,int end)
{
int mid=(start+end)/2;
int l=start,k=start,r=mid+1;
while((l
{
if(src[l]
tem[k++]=src[l++];
else
tem[k++]=src[r++];
}
while(l
tem[k++]=src[l++];;
while(r
tem[k++]=src[r++];
for(l=start;l
src[l]=tem[l];
}
void mergersort(int* src,int* tem,int start,int end)
{
if(start
{
mergersort(src,tem,start,(start+end)/2);
mergersort(src,tem,(start+end)/2+1,end);
mergerarray(src,tem,start,end);
}
}
void quicksort(int* src,int start,int end)
{
int l=start,r=end;
int key=0;
if(start>=end)
return;
key=src[l];
src[l]=src[(start+end)/2];
src[(start+end)/2]=key;
while(l
{
while((l
r--;
if(l
src[l++]=src[r];
while((l=src[l]))
l++;
if(l<r)
src[r--]=src[l];
}
src[l]=key;
quicksort(src,start,l-1);
quicksort(src,l+1,end);
}
int main(void)
{
int* src=NULL;
int* tem=NULL;
int n=10000000;
int i=0;
clock_t start,end;
double duration;
src=(int*)malloc(n*sizeof(int));
tem=(int*)malloc(n*sizeof(int));
for(i=0;i<n;i++)
src[i]=rand();
start=clock();
//////////////排序/////////////////////////////////
// mergersort(src,tem,0,n-1);
quicksort(src,0,n-1);
////////////////////////////////////////////////
end=clock();
duration=(end-start)*1000/CLOCKS_PER_SEC;
printf("耗时%f毫秒nn",duration);
free(src);
free(tem);
return 0;
}

                 快速排序(ms)   归并排序(ms)

1百万数据 141 187
1千万数据 4119 2262

当排序的数据量不大时,快排的速度大于归并排序,
当排序的数据比较大时,归并排序的速度大于快排,
是不是cache命中率的原因
哪位大神可以解释一下

解决方案

如果数据是基本有序的,那么归并更快一点不奇怪。也可能是cache的原因。要用性能热点分析工具才知道

解决方案二:

快速排序快速排序的最坏情况基于每次划分对主元的选择。基本的快速排序选取第一个元素作为主元。这样在数组已经有序的情况下,每次划分将得到最坏的结果。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为主元。这种情况下虽然最坏情况仍然是O(n^2),但最坏情况不再依赖于输入数据,而是由于随机函数取值不佳。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2^n)。所以随机化快速排序可以对于绝大多数输入数据达到O(nlogn)的期望时间复杂度。一位前辈做出了一个精辟的总结:“随机化快速排序可以满足一个人一辈子的人品需求。”
随机化快速排序的唯一缺点在于,一旦输入数据中有很多的相同数据,随机化的效果将直接减弱。对于极限情况,即对于n个相同的数排序,随机化快速排序的时间复杂度将毫无疑问的降低到O(n^2)。解决方法是用一种方法进行扫描,使没有交换的情况下主元保留在原位置。
综合来说快速排序速度最快,时间复杂度最小。

时间: 2024-08-01 13:47:07

关于快速排序和归并排序的速度问题的相关文章

JavaScript希尔排序、快速排序、归并排序算法_javascript技巧

以var a = [4,2,6,3,1,9,5,7,8,0];为例子. 1.希尔排序. 希尔排序是在插入排序上面做的升级.是先跟距离较远的进行比较的一些方法. function shellsort(arr){ var i,k,j,len=arr.length,gap = Math.ceil(len/2),temp; while(gap>0){ for (var k = 0; k < gap; k++) { var tagArr = []; tagArr.push(arr[k]) for (i

归并排序

下面简单的说说归并排序,所谓归并排序就是说把输入数组分成两组当然也可以大于2组,一般我们是等量的分成2组,通过递归我们可以把长度为n的数组分成n个数组,我们通过一定的关键字比较把两两结合成一个有序的数组,然后回溯到原数组大小的有序数组,具体的我就不多说了,因为比较简单,到网上可以找些相关文章看看什么是归并排序,归并排序算法可以再O(nlogn)的时间内对长度为n的序列完成排序,至于合并两个有序数组,假如这两个数组的长度分别为m和n,那么我们只需要O(n+m)的时间久可以完成对这两个有序数组的合并

Java实现快速排序算法(Quicktsort)

 这篇文章主要介绍了Java实现快速排序算法(Quicktsort),有需要的朋友可以参考一下 快速排序算法介绍 快速排序和归并排序都使用分治法来设计算法,区别在于归并排序把数组分为两个基本等长的子数组,分别排好序之后还要进行归并(Merge)操作,而快速排序拆分子数组的时候显得更有艺术,取一个基准元素,拆分之后基准元素左边的元素都比基准元素小,右边的元素都不小于基准元素,这样只需要分别对两个子数组排序即可,不再像归并排序一样需要归并操作.基准元素的选取对算法的效率影响很大,最好的情况是两个子数

《算法基础:打开算法之门》一3.5 快速排序

3.5 快速排序 像归并排序那样,快速排序也使用分治模式(因此也使用递归).然而,快速排序与归并排序所使用的分治法稍微有点不同.与归并排序相比,存在两个不同之处: ●快速排序按照原址工作. ●快速排序的渐近运行时间介于最坏情况和平均情况之间.尤其是,快速排序的最坏运行时间是Θ(n2),但是它的平均情况下的运行时间要更好一些:Θ(nlgn).快速排序也有好的常数因子(比归并排序更好一些),并且它通常是实践中的一个好的排序算法.这里是快速排序使用分治法的过程.再一次考虑对书架上的书进行排序的例子.就

归并排序的实现代码与思路_java

首先考虑下如何将将二个有序数列合并.这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数.然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可. 复制代码 代码如下: View Code  //将有序数组a[]和b[]合并到c[]中 void MemeryArray(int a[], int n, int b[], int m, int c[]) {     int i, j, k;      i = j = k = 0;     while

Java实现快速排序算法(Quicktsort)_java

快速排序算法介绍快速排序和归并排序都使用分治法来设计算法,区别在于归并排序把数组分为两个基本等长的子数组,分别排好序之后还要进行归并(Merge)操作,而快速排序拆分子数组的时候显得更有艺术,取一个基准元素,拆分之后基准元素左边的元素都比基准元素小,右边的元素都不小于基准元素,这样只需要分别对两个子数组排序即可,不再像归并排序一样需要归并操作.基准元素的选取对算法的效率影响很大,最好的情况是两个子数组大小基本相当.为简单起见,我们选择最后一个元素,更高级的做法可以先找一个中位数并把中位数与最后一

数据排序谁最快(javascript中的Array.prototype.sort PK 快速排序)_javascript技巧

但是让我感到意外的是,下面有个网友回复说,javascript中的Array本身的sort方法才是最快的,比快速排序算法都快,当时看到了很是郁闷,因为当时花了好长时间在排序算法上,居然忘记了Array本身的sort方法 不过javascript中内置的sort方法真的比快速排序算法还快吗? 哈哈,测试一下不就知道了 先说一下我测试的环境 1,我的测试环境是IE6.0和firefox2.0 2,每种算法有很多种不同的实现方法,下面测试中我选择上面网友实现的快速排序算法,只是把内嵌函数搬到了外面 3

各种排序算法的总结和比较

1 快速排序(QuickSort) 快速排序是一个就地排序,分而治之,大规模递归的算法.从本质上来说,它是归并排序的就地版本.快速排序可以由下面四步组成. (1) 如果不多于1个数据,直接返回. (2) 一般选择序列最左边的值作为支点数据. (3) 将序列分成2部分,一部分都大于支点数据,另外一部分都小于支点数据. (4) 对两边利用递归排序数列. 快速排序比大部分排序算法都要快.尽管我们可以在某些特殊的情况下写出比快速排序快的算法,但是就通常情况而言,没有比它更快的了.快速排序是递归的,对于内

各种排序算法的分析及java实现

排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于下半年要准备工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间重新研究了一下. 排序大的分类可以分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序.下面讲的排序都是属于内排序. 内排序有可以分为以下几类: (1).插入排序:直接插入排序.二分法插入排序.希尔排序. (2).选择排序:简单选择排序.堆排序.