【算法 - 基础】快速排序
思想
快速排序基于分治的策略,它的基本步骤是:
- 选定一个数据 x 为基准
- 将比 x 小的数据移到 x 的一边,将比 x 大的数据移到另外一边
- 对左右两边重复这个操作
当然这种说法可能不太容易理解,因此在这里我说一说我的写法
- 想要按从小到大的顺序排一个序列 ,可以先以这个序列的中间数据为基准分为左右两个部分。左边为比基准数小的数据,右边为比基准数大的数据。
- 当左右两个序列排列好后,自然而然就能得到一个排好的序列。
- 而要排列左右两序列,我们则又可以按照1的步骤来。
- 当序列不能再分了,我们的排序就好了
实现(C/C++)
快速排序模板
//快速排序
void quick_sort(int q[],int l,int r){
//l代表区间的最左边,r代表区间的最右边
//递归边界
if(l==r) return; //写成 if(l>=r) return; 也行
//按一个方式,将序列分为左右两个序列
int i=l-1; // i相当于左边的指针,一开始不指向任何数据
int j=r+1; // j相当于右边的指针,一开始不指向任何数据
int x=q[l+r>>1]; //x表示基准,这里表示以中间为基准
//开始划分
while(i<j){
// 类似简单选择排序的标记交换步骤
while(q[++i]<x); //左序列 存比 x 小的数据,找到了一个比 x 大的就停止
while(q[--j]>x); //右序列 存比 x 大的数据,找到了一个比 x 小的就停止
if(i<j){
// 如果此时 i还小于j 就交换,否则不用交换
// 左右指针相遇就代表已经划分完毕
int t=q[j];
q[j] = q[i];
q[i] = t;
}
}
//重复操作
quick_sort(q,l,j);
quick_sort(q,j+1,r);
}
时间复杂度与空间复杂度
快速排序的时间复杂度
最优情况下:O( nlogn )
最差情况下:O( n^2 )
平均时间复杂度:O( nlogn )
快速排序的空间复杂度
最优情况下:O(logn)
最差情况下:O( n )
平均时间复杂度:O( nlogn )
库函数的使用
c++的algorithm库中提供了一个快速排序的函数 sort(),在实际运用中,我们可以直接调用 sort 函数即可,sort 函数有两种形式
- sort ( right, left ) : 将 right, left 按从小到大的顺序进行排序
- sort ( right, left, check) : 将 right, left 按指定的规则进行排序, check 为我们自己定义的一个排序规则,返回值为bool类型
例
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6+10;
int a[N];
bool cmp(int i,int j){
return i>j; // 按照从大到小的规则排序
}//自定义的排序规则,从大到小排序
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n); //按从小到大的顺序进行快速排序
for(int i=0;i<n;i++)
printf("%d",a[i]);
sort(a,a+n,cmp);//按从大到小的顺序进行快速排序
for(int i=0;i<n;i++)
printf("%d",a[i]);
return 0;
}
练习题 and 题解(不定期更新)
学完知识点我们来一点题目练练手吧!
例题一
题目描述
链接: 【模板】快速排序
思路
这题就是一个很简单的模板题,直接拿模板来用就行
AC代码:
#include <iostream>
using namespace std;
const int N = 100010;
int n;
int a[N];
void quick_sort(int q[],int l,int r)
{
if(l>=r) return;
int i=l-1,j=r+1,x=q[l+r>>1];
while(i<j){
while(q[++i]<x);
while(q[--j]>x);
if(i<j) swap(q[i],q[j]);
}
quick_sort(q,l,j);
quick_sort(q,j+1,r);
}
int main(){
cin>>n;
for(int i=0;i<n;i++) scanf("%d",&a[i]);
quick_sort(a,0,n-1);
for(int i=0;i<n;i++) printf("%d ",a[i]);
return 0;
}
例题二
链接: 【深基9.例4】求第 k 小的数
例题三
链接: 【NOIP2006 普及组】 明明的随机数