快速排序实现与分析
来源:互联网 发布:什么叫数字字符c语言 编辑:程序博客网 时间:2024/05/21 06:29
问题描述:快速排序是数据结构中经典算法,在各种内部排序中拥有非常高的效率——时间复杂度为O(NlogN),同时常数因子最小,但是同时也有可能出现最坏情况——在待排序元素几乎有序或者完全有序时候性能非常差,时间复杂度退化到O(N*N)。对快速排序性能影响最关键的就是基准元素的选择,所以为了平滑最坏情况,本程序使用了随机选择基准元素的方法。当然,聪明的读者可能会这样问到,就算随机选择,也有可能随机选择到的基准元素为最大或者最小的元素(这是出现最坏性能的情况),当然我们不排除这种可能。不过鉴于我们随机选择划分元,出现这种情况的概率非常小,也就是说,我们只有最坏的情况,但是不会出现最坏的实例了。如果要完全避免这种最坏的情况,可以使用中位数的方法选择划分元,这个方法相对比较麻烦,在此就不说了。
说得太多了,上面的最坏情况、最坏实例的区别可能大家一时无法理解,不过也没事,我们不讨论这个问题了,毕竟过于专业化了。为了便于大家对快速排序的性能有个感性上的认识,代码中给出了一个对比的排序——冒泡排序,相信学过C语言或者其他语言的读者对这个排序不会陌生的。实例中,我做了10万个随机整数的排序,快速排序需要58clocks,而冒泡排序需要123720clocks,至于一个clokc是多少秒我也没有查了,反正就是个时间基准单元吧。可以看出,对于10万个数据的排序,冒泡排序花的时间是快速排序的2000倍以上。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAXLEN 10000//请大家注意这个MAXLEN不能太大,因为程序(进程)栈空间有限
//使用type替代int为了方便比较不同类型的数据,
//但是如果使用其他类型的数据或许需要根据情况进行运算符重载
typedef int type;
#define do_swap(x,y) {type tmp;tmp=x;x=y;y=tmp;}//使用宏展开式为了避免频繁函数调用的开销
int partion(type a[],int p,int r)
{
type x=a[p];
int i=p,j=r+1;
while(1)
{
while(a[++i]<x&&i<r);
while(a[--j]>x) ;
if(i>=j) break;
do_swap(a[i],a[j]);
}
a[p]=a[j];
a[j]=x;
return j;
}
int randpartion(type a[],int p,int r)
{
if(p<r){
int x=p+rand()%(r-p);
do_swap(a[p],a[x]);
}
return partion(a,p,r);
}
void quicksort(type a[],int p,int r)//快速排序
{
if(p<r){
int q=randpartion(a,p,r);//使用随机选择划分元,平滑最坏的实例
//int q=partion(a,p,r);//未使用随机选择划分元,划分元固定选择为a[p]
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}
void bubblesort(type a[],int p,int r)//冒泡排序
{
int i,j;
for(i=p;i<=r;++i)//在此处i++,++i效果相同,可能大家问到为什么使用++i而不使用i++,
//这个比较微妙,相信不是每个人都有兴趣知道,不废话了。
for(j=i+1;j<=r;++j)
if(a[i]>a[j]){
do_swap(a[i],a[j]);
}
}
int main()
{
type a[MAXLEN],b[MAXLEN];
int i;
srand(time(NULL));
for(i=0;i<MAXLEN;++i)
{
b[i]=a[i]=rand();
}
time_t start_of_quicksort,end_of_quicksort;
time_t start_of_bubblesort,end_of_bubblesort;
start_of_bubblesort=clock();
bubblesort(b,0,MAXLEN-1);
end_of_bubblesort=clock();
start_of_quicksort=clock();
quicksort(a,0,MAXLEN-1);
//quicksort(b,0,MAXLEN-1);//可以在使用未随机选择划分元的情况,测试快速排序的最坏实例
end_of_quicksort=clock();
//观看排序后的结果,如果不想看结果可以屏蔽这段代码
for(i=0;i<MAXLEN;++i)
{
printf("%6d",a[i]);
if(i%10==9) printf("/n");
}
printf("/n******************************************************/n");
printf("********************************************************/n");
printf("*****************************************************/n");
printf("*******************************************************/n");
for(i=0;i<MAXLEN;++i)
{
printf("%6d",b[i]);
if(i%10==9) printf("/n");
}
printf("/n");
printf("*******************************************************/n");
printf("%the time of quicksort is :%ld clocks/n",end_of_quicksort-start_of_quicksort);
printf("%the time of bubblesort is :%ld clocks/n",end_of_bubblesort-start_of_bubblesort);
return 0;
}
- 快速排序实现与分析
- 快速排序分析与实现
- 快速排序方法Java实现与分析
- 快速排序分析与C语言实现
- QuickSort 快速排序的分析与实现
- 快速排序的经典实现与分析
- 快速排序算法的分析与实现
- 快速排序实现分析
- 排序算法—快速排序算法分析与实现(Python)
- 算法设计与分析 快速排序的递归实现算法
- 快速排序介绍与分析
- 排序算法的C++实现与性能分析(插入排序、归并排序、快速排序、STOOGE排序、堆排序)
- 排序系列--快速排序(实现+复杂度分析)
- 数据结构与算法分析笔记与总结(java实现)--排序5:快速排序练习题
- 快速排序 原理与实现
- 快速排序探索与实现
- 快速排序详解与实现
- 快速排序 与 随机快速排序 算法分析
- 工作
- "SocketException: 由于线程退出或应用程序请求,已放弃I/O操作" 解决方案
- ProgressBar 各种样式
- 客户访谈:汇添富基金:后金融危机时代决胜基金业之道
- flash与动画:打字动画
- 快速排序实现与分析
- Oracle杀锁
- Linux 启动全过程
- ARM中的RO、RW和ZI DATA说明 (转)
- Linux系统的常用操作命令
- Javascript prototype详解
- ProgressBar 风格2
- 美好的天天
- java.lang.NoSuchMethodError: javax.persistence.Persistence.getPersistenceUtil()Ljavax/persistence/PersistenceUtil解决方案