快速排序
将一串数组分成四部分,有一个主元x,x的左边都比x小,x的右边都比x大。一开始选择数组的最后一个数作为主元x,然后以i记录比主元小的部分,以j记录比主元大的部分,还有一个主元部分,剩下是还未扫描到的部分。
(黄色为大于主元的子数组)
i,p,j r
| 2 | 8 | 7 | 1 | 3 | 5 | 6 | 4 |
| 2 | 8 | 7 | 1 | 3 | 5 | 6 | 4 |
| 2 | 8 | 7 | 1 | 3 | 5 | 6 | 4 |
| 2 | 8 | 7 | 1 | 3 | 5 | 6 | 4 |
| 2 | 1 | 7 | 8 | 3 | 5 | 6 | 4 |
| 2 | 1 | 3 | 8 | 7 | 5 | 6 | 4 |
| 2 | 1 | 3 | 8 | 7 | 5 | 6 | 4 |
| 2 | 1 | 3 | 8 | 7 | 5 | 6 | 4 |
| 2 | 1 | 3 | 4 | 8 | 7 | 5 | 6 |
找出主元并将数组分两边
int Partition(int a[],int p,int r){//设置一个主元,将数组分成两边,左边都小于主元,右边都大于主元
int x = a[r];//将最后一个数设为主元
int i = p - 1;
int j;
for(j=p;j<r;j++){//往后扫描数组(扩大大于大于主元的数组)
if(a[j] <= x){//如果所扫描到的值属于左边(小于主元)
i += 1;//扩大左边(小于主元)的数组
exchange(a,i,j);//将扫描到的值放进左边数组。
}
}
exchange(a,i+1,r);//将主元放到两个数组中间
return i+1;
}
快排
void QuickSort(int a[],int p,int r){
if(p<r){
int q = Partition(a,p,r);
QuickSort(a,p,q-1);
QuickSort(a,q+1,r);
}
}
还有一个随机版快排,即在数组 A[p…r]中随机选择一个数作为主元。因为如果快排划分不平衡,那它的性能就接近插入排序,若主元是随机的,那在平均情况下对数组的划分是比较平衡的。
int Random_Partition(int a[],int p,int r){//在数组中随机选一个数作为主元
int i = Random(p,r);
exchange(a,r,i);
return Partition(a,p,r);
}
void Random_QuickSort(int a[],int p,int r){
if(p<r){
int q = Random_Partition(a,p,r);
Random_QuickSort(a,p,q-1);
Random_QuickSort(a,q+1,r);
}
}
接下来是完整源码:
#include <stdio.h>
#include <time.h>
int Random(int a,int b){//在a,b(连续)之间产生一个随机数
srand((int)time(NULL));
return rand()%(b-a+1)+a;
}
void exchange(int a[],int m,int n){//交换数组里的两个数
int tmp;
tmp = a[m];
a[m] = a[n];
a[n] = tmp;
}
int Partition(int a[],int p,int r){//设置一个主元,将数组分成两边,左边都小于主元,右边都大于主元
int x = a[r];//将最后一个数设为主元
int i = p - 1;
int j;
for(j=p;j<r;j++){//往后扫描数组(扩大大于大于主元的数组)
if(a[j] <= x){//如果所扫描到的值属于左边(小于主元)
i += 1;//扩大左边(小于主元)的数组
exchange(a,i,j);//将扫描到的值放进左边数组。
}
}
exchange(a,i+1,r);//将主元放到两个数组中间
return i+1;
}
void QuickSort(int a[],int p,int r){
if(p<r){
int q = Partition(a,p,r);
QuickSort(a,p,q-1);
QuickSort(a,q+1,r);
}
}
int Random_Partition(int a[],int p,int r){//在数组中随机选一个数作为主元
int i = Random(p,r);
exchange(a,r,i);
return Partition(a,p,r);
}
void Random_QuickSort(int a[],int p,int r){
if(p<r){
int q = Random_Partition(a,p,r);
Random_QuickSort(a,p,q-1);
Random_QuickSort(a,q+1,r);
}
}
int main(){
int a[8] = {2,8,7,1,3,5,6,4};
int length = sizeof(a)/sizeof(int);
int i;
for(i=0;i<length;i++){
printf("a[%d]=%d ",i,a[i]);
}
// QuickSort(a,0,length-1);
Random_QuickSort(a,0,length-1);
printf("\n");
for(i=0;i<length;i++){
printf("a[%d]=%d ",i,a[i]);
}
return 0;
}
参考:《算法导论》