快速排序可以说是最为常见的排序算法,冒泡排序时间复杂度达到了O(N2),而桶排序容易造成浪费空间。快排(Quicksort)就成为了不错的选择。
1、原理:快排需要找一个数作为基准数,用来参照。(可取第一个数为参照)
基准数在中间某位置,两端有指针,找到相应数后,交换。
注意:若令第一个数为基准数,先从右往左找,再从左往右找。
2、优点:平均时间复杂度O(NlogN),相比冒泡排序每次交换可以是跳跃式的
排序过程:
代码:
#include<stdio.h>
int a[101],n;//定义全局变量,需要在子函数中使用
void quicksort(int left,int right){
int i,j,t,temp;
if(left>right)
return;
temp=a[left];//用来存基准数
i=left;
j=right;
while(i!=j){
//从右往左找
while(a[j]>=temp&&i<j)
j--;
//从左往右找
while(a[j]<=temp&&i<j)
i++;
//swap
if(i<j){
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
//基准数归位
a[left]=a[i];
a[i]=temp;
quicksort(left,i-1);//递归
quicksort(i+1,right);//递归
return;
}
int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
quicksort(1,n);
for(i=1;i<=n;i++){
printf("%d ",a[i]);
}
//getchar();getchar();
return 0;
}
3、通过改变基准数的选取来优化代码
4、结构体+快排(以科目+成绩为例)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct S{
char subject[2000];
long int score;
}subject[1001],p,temp;
void Qsort (int left,int right){
int i,j,t;
if(left>right){
return;
}
temp=subject[left];
i=left;
j=right;
while(subject[j].score>=temp.score&&i<j){
j--;
}
while(subject[i].score<=temp.score&&i<j){
i++;
}
if(i<j){
p=subject[i];
subject[i]=subject[j];
subject[j]=p;
}
subject[left]=subject[i];
subject[i]=temp;
Qsort(left,i-1);
Qsort(i+1,right);
}
int main(){
long int num=0;
scanf("%ld",&num);
struct S t;
for(long int i=1;i<=num;++i){
scanf("%s %ld",subject[i].subject,&subject[i].score);
}
Qsort(1,num);
for(long int i=1;i<=num;i++){
printf("%s ",subject[i].subject);
}
return 0;
}
5、qsort函数
为了使用方便,C语言在库中自带了快排函数
函数原型
#include<stdlib.h>
void qsort(void*, size_t, size_t, int ( * )(const void * , const void * ))
1、第一个参数为待排序数组首地址。
可直接输入待排序数组名,或是指向数组的指针。2、第二个参数为数组长度。
size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int。
可以直接输入待排序的数组的长度。3、第三个参数为数组元素所占字节。
可直接用sizeof(a[0])计算字数组单个元素的节数。4、第四个参数为所调用函数的指针,函数名即是函数的指针,可直接写函数名,调用函数用来确定排序的方式。