快速排序
#排序+二分思想
#分析+代码
排序
- 桶排序 (复杂度O(M+N),M是数的个数,N是桶的大小,不再赘述)
- 快速排序
- qsort函数排序(quick sort)
- sort函数排序(一般用qsort,我记得sort在数据量大或者数据大的时候会出错?)
- 冒泡排序(死都不用)
简而言之,就是快速的排序,为什么说它是快速排序呢?因为它相比于其他排序综合来说是使用最多的一个排序,在c++中有一个qsort排序函数,即quicksort,快排的时间复杂度是O(N*logN)。
问题描述如下:N是数的个数,N=10000,最大整数的范围接近int的最大值,如何排序?
分析:如果使用冒泡排序的话,时间复杂度为O(N * N),运算次数大概1e8次,放心吧,一般题目不会让你过的。这种情况一定会超过一秒,题目的本意就是让你用快排,在大小为10000的数组空间下使用快速排序,大概运算14*10000次,远小于1e8次运算,所以在时间充足的条件下,完全可以解决这类问题。
在学习算法入门的基础上,不用担心其他问题对排序的为难,快排撑场子。
所以啊,我这只是对快排絮叨一下。
代码
//让我唯一恼火过的细节问题:i和j“探测”的while循环条件中为什么要加上等于号?因为基准值选的是左边,所以在i移动的while循环中加上num[i]<=base,就不会出错,但是j>=num[i]也没有错,所以最好的方法是两者都加上 =
#include<stdio.h>
int num[110];
//如果有n个数
// 闭区间 [1,n] 或者 [0,n-1]
void quicksort(int left,int right)
{
int i=left;
int j=right;
//选一个基准值
int base=num[left];
int t;
//以left大于right为程序的出口
if(left>right)
return;
//当i和j不相等的时候,
//先找右侧小于基准值的值,再找左边大于基准值的值,
//j--,右侧找到或者与i相等,跳出内循环。
//i++,左侧找到或者与j相等,跳出内循环。
//直到i==j跳出最外层的循环。
while(i!=j){
//执行某一段的时候,只有两种情况,
//要么是找到可以交换的数,要么i和j相等
while(num[j]>=base&&j>i){
j--;
}
while(num[i]<=base&&i<j){
i++;
}
//交换
t=num[i];
num[i]=num[j];
num[j]=t;
}
num[left]=num[i];
num[i]=base;
quicksort(left,i-1);
quicksort(i+1,right);
return;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
quicksort(0,n-1);
for(int i=0;i<n-1;i++)
printf("%d ",num[i]);
printf("%d\n",num[n-1]);
}