您的位置:首页 > 其它

快速排序及其随机化(算法导论)

2018-01-30 10:06 381 查看
如果对快速排序和分治不是很熟悉,建议先观看网易公开课上与算法导论配套的麻省理工的算法导论课程。

算法描述

简单来说,输入一组数,选取一个作为主元,遍历整个数组,将比主元小的数扔到主元左边,比主元大的数扔到主元右边,然后对主元的左右两个区间再次这样排序,直到整个数组排序完成。

特点

适用于数据多,范围小,且经常重复的数据,不适合范围大,分化严重的数据。初始数组越接近顺序排列,此排序耗时越长。此法平均复杂度比插入排序小很多,但它不需要额外的空间。归并排序虽然最快,却需要大量的额外空间。

输入的数据大多时候并非随机的,所以我们要在排序过程中打乱其原有顺序,使得分布更加均匀。

读本代码需要注意的几个地方

输入只有一串不确定的数字。因此,为了节省空间,我用了一个队列计算和暂存数字N,再依据N来建立数组。

由于无法将数组作为实参传递给函数,所以本代码使用了指针。由于指针操作的数组内存必须连续,所以我用malloc函数来申请数组空间。

两个快排函数可以参考算法导论一书。

代码

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;

//快速排序

void EXCHANGE(int *Array,int i,int j)
{
int key=Array[i];Array[i]=Array[j];Array[j]=key;
}

int PARTITION(int*Array,int p,int r)//返回一轮排序后主元位置
{
int k=rand()%(r-p+1)+p;//产生一个p到r的随机整数
EXCHANGE(Array,k,r);//交换A[k]与A[r]
int x=Array[r],i=p-1;
for(int j=p;j<r;j++)
{
if(Array[j]<x)
{
i++;
EXCHANGE(Array,i,j);//交换A[i]和A[j]。
}
}
i++;
EXCHANGE(Array,i,r);//交换A[++i]和A[r]
return i;
}

void QUIKSORT(int*Array,int p,int r)
{
if(p<r)
{
int q=PARTITION(Array,p,r);
QUIKSORT(Array,p,q-1);
QUIKSORT(Array,q+1,r);
}
}

int main()
{
int key,N=0;
queue<int>import;
while(scanf("%d",&key)!=EOF)
{
N++;
import.push(key);
}
int *Array=(int*)malloc(sizeof(int)*(N+1));//定义并初始化Array
for(int i=1;i<=N;i++)
{
key=import.front();
import.pop();
Array[i]=key;
}
QUIKSORT(Array,1,N);
for(int j=1;j<=N;j++) printf("%d  ",Array[j]);
printf("\n");
return 0;
}


嗯,有什么问题请留言。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: