快速排序,其原理和合并排序一样,基于分治法,分割的时间是O(n),分割的次数是O(logn),所以其时间复杂度为O(nlogn)。
这里介绍两种方法实现
方法一
首先选择一个基准数,这里以最右边的数为例。然后从最左边开始找,只要小于基准数就把它交换到前面,这样共比较了n次,假设这里交换到前面的数有i个,那么第i+1的位置就是基准数的位置。
然后以基准数为分界线把需要排序的数组分为左右两部分。
继续对子数组进行分割,直到其长度为1。
/*
样例
15
13 19 9 5 12 8 7 4 21 2 5 3 14 6 11
*/
#include<iostream>
#include<cstdlib>//swap函数
using namespace std;
const int N=(int)(1e5);
int a[N];
int n;
int partition(int l,int r){
int i;
int j;
int tmp;
int s=a[r];//基准数
i=l;
for(j=l;j<r;j++){//从左边开始找,小于基准数的从左边第一个开始放
if(a[j]<=s){
swap(a[i++],a[j]);
}
}
swap(a[i],a[r]);//直到所有小于基准数的都放在了左边,那么此时i指向的位置就是基准数的位置
return i;
}
void quickSort(int l,int r){
int mid;
if(l<r){
mid=partition(l,r);
quickSort(l,mid-1);
quickSort(mid+1,r);
}
}
void read(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
}
void print(){
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
int main(){
read();
quickSort(0,n-1);
print();
}
参考资料:《挑战程序设计竞赛》
方法二
#include <stdio.h>
void swap(int a[], int i, int j)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int partition(int a[], int p, int r)
{
int i = p;//最后指向大于x的
int j = r + 1;//最后指向小于x的
int x = a[p];//标尺
while(1){
while(i<r && a[++i]<x);
while(a[--j]>x);// x j i
if(i>=j) break;//这里比如i最终指向5,j最终指向2,其原始顺序是3 . 2 5 . .
swap(a,i,j);
}
swap(a,p,j);//这里一定是与j换,因为要把小于x的和x换
return j;
}
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 main()
{
int i; //
int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
int N = 12;
quicksort(a, 0, N-1);
for(i=0; i<N; i++) printf("%d ", a[i]);
printf("\n");
return 0;
}