思路1
借鉴了某篇写得很棒的博客!博主非常用心,分享给大家学习参考
- 思路1简单来讲就是左右开弓,左边右边一起找,找到符合要求的就两两交换
1、 随机取出一个数,将这个位置的数与最左端的数交换一次,并将左端数作为基准参考数(当然可以直接去最左端的数为基准数)
2、 定义两个指针i和j,分别是从左往右和从右往左找的标记
3、 从右边开始(注意一定是从右边开始往左边找,不然会出问题)向左找比基准数小的数,找到比base小的数后指针j就定位到了该数,再从左往右找比base大的数,但是注意终止条件是i与j重合,所以要在j指针的左侧找,找不到就让i位置不动即可
4、 让i与j对应的数交换一次
5、 如果i与j尚未重合,则继续上述操作,能找到满足条件的就继续,找不到就说明这一轮结束
6、 此时,这个基准数已经交换到了它排序后的正确位置上,左侧的数都比它小,右侧都比它大,但是这时左右的数是并没有排好序的
7、分别对左右的数重复上述操作,一步步将所有基准数放置到排序后的正确位置上(使用了递归和分治的思想)
看到一篇博客,非常喜欢,博主很用心在写快速排序算法的图解博客,分享出来:
链接: 快速排序法(详解)
思路2
参考资料链接:runoob 快速排序
其实整体上和思路1是差不多的,看了很多教程,下面这种理解更普适一下,所以着重提一下,
- 思路2呢,简单来讲就是填坑,右边满足数复制到左边,相当于右边腾出了一个空间存左边找到的满足数…
1、选取最左端为基准数
2、从右侧找比基准数小的数
3、将右边这个数填到左侧指针的位置上
4、然后从左找到比基准数大的数,填坑到右侧坑上
5、终止添加是两个指针重合,此时实现了将本轮的基准数放在正确的位置
5、分治和递归思想思想重复上述操作即可将每一轮的基准数归位
#include<bits/stdc++.h>
using namespace std;
int a[10001],n;
void quick_sort(int left,int right){
if(left>=right) return;//如果左大于右或只有一个数,就直接返回
swap(a[left],a[rand()%(right-left+1)+left]);//从数组中随机找一个数交换到左端作为基准数
int i=left,j=right,base=a[left];
while(i<j){//左右标记指针未重合
while(i<j&&a[j]>=base) j--;//先从右往左找比base大的
if(i<j) a[i++]=a[j];//填坑到前面
while(i<j&&a[i]<=base) i++;//后从右往左找比base小的
if(i<j) a[j--]=a[i]; //填坑到后面
}
a[i]=base;//最后i,j重合处也就是基准数的坑
/*分治*/
quick_sort(left,i-1);
quick_sort(i+1,right);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
srand(int(time(0)));//让快排中rand值每次不同,基准数随机
quick_sort(1,n);
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
return 0;
}
数据测试:
10
23 32 44 1 65 45 90 94 52 6
1 6 23 32 44 45 52 65 90 94