首先是伪代码
QuickSort(A[l...r])
//用QuickSort对子数组进行排序
//输入:叔祖A[0...n-1]中子数组A[l..r],由左右下标l和r定义
//输出:非降序排列的子数组A[l...r]
if l<r
s<-Partition(A[l.r])//找到轴值,并且划分数组
QuickSort(A[l...s-1])
QuickSort(A[s+1...r])
LomutoPartition划分方法
LomutoPartition(A[l...r])
//采用LomutoPartition算法,用第一个元素作为中轴对子数组进行划分
//输入:数组A[0...n-1]的一个子数组A[l..r],它由左右二边的索引l和r定义
//输出:A[l..r]的划分和中轴的新位置
//第一步,先选取第一个元素为轴值
1.p<-A[l]
//第二步,s为首指针,给s赋初值
2.s<-l
//第三步,排序
3.for i<-l+1 to r do
if A[i]<p
s<-s+1;swap(A[s],A[i])
//第四步,把轴值放到它的位置
4.swap(A[l],A[s])
return s
就是将比p小的数字放到p的前面
HoarePartition算法
HoarePartition(A[l...r])
//以第一个元素为中轴,对子数组进行划分
//输入:数组A[0...n-1]中的子集A[l...r],由左右下标l和r定义
//输出:A[l...r]的一个划分,分裂点作为函数的返回值
//第一步,选取第一个元素为轴值
1.p<-A[l]
//第二步,设置一个首指针,一个尾指针
2.i<- l;j<-r+1;
//第三步,i从l+l加一开始,j从r开始(这俩个repeat是并列的)
3.repeat(重复)
repeat i<- i+1 until A[i]>=p
repeat j<- j-1 until A[j]<=p
swap(A[i],A[j])
//结束条件:i>=j
until i>=j
//第四步
//当i>=j撤销最后一次交换
4.swap(A[i],A[j])
//第五步,将轴值换到本来的位置
5.swap(A[l],A[j])
return j
接下来是代码实现
大致思想一样,可能有些步骤与算法不太一样
//hoare算法
//HoarePartition排序
int HoarePartition(int *a,int l,int r){
//选取第一个元素为轴值
int key=l;
//定义一个首指针一个尾指针
int i=l,j=r;
//开始排序
while(i<j){
while(i<j && a[i]<=a[key]){
i++;
}
while(i<j && a[j]>=a[key]){
j--;
}
swap(a[i],a[j]);
}
//把轴值放在它的位置
swap(a[i],a[key]);
//找到下一个轴值
key=i;
return key;
}
//快排函数
void Qsort(int *a,int begin,int end){
if(begin>=end) return;
int key=HoarePatition(a,begin,end);//每次都返回轴值
//划分左区间
Qsort(a,begin,key-1);
Qsort(a,key+1,end);
}
//LomutoPartition算法
int LomutoPartition(int *a,int l,int r){
int p=a[l];
int s=l;
for(int i=l+1;i<=r;i++){
if(a[i]<p)
{
s=s+1;
swap(&a[s],&a[i]);
}
}
swap(&a[l],&a[s]);
return s;
}
2024年10月6日更新
2024年10月13日发现还有一些问题,晚上再修改一下