今天在复习C++算法时,复习到了快速排序,并且从别处学到一种非常好的方法,所以想分享一下,故作此文
在此先给出一道快速排序的题
(此题选自acwing中)这里便以样例来看
首先要知道快速排序是什么意思:
任取数组里的任意一个数,使这个数左边的数都小于x,右边的数都大于x,这里我们让i不断向右,直到i所指的数不符合小于x这个条件;再让j不断向左,直到j在、所指的数不再符号大于x这个条件;再让a[i]与a[j]的内容互换一下;最后在x两边重复这一操作,直到排列完成
这样说是不是感觉很迷糊?
没事,我们用样例一步一步来模拟一下过程
这是i与j最初的位置;
此时x=2;
此时a[i]已经不满足条件,让他停下,去操作j
此时a[j]=x,j停下
交换a[i]和a[j]的值
之后两边的排列是完全相同的方法,这里就不再画图说明过程
接下来是完整的代码
#include <iostream>
using namespace std;
//快速排列
const int N = 10010;
int q[N];
void quick_sort(int q[], int l, int r)
{
//l表示左端点,r表示右端点
if (l >= r) return;//左端点大于右端点,退出函数
int x = q[(l+r)/2];//任意点都可以,为了方便记,统一记为这样
int i = l - 1;
int j = r + 1;//后面的do~while循环会让i与j++,所以这里提前先-1
while (i < j)//循环条件
{
do i++; while (q[i] < x);//让所有x左边的值都小于x
do j--; while (q[j] > x);//让所有x右边的值都小于x
if (i < j) swap(q[i], q[j]);//直到两个条件都不满足就交换一下值
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);//以同样的方法再次快速排列两边
}
int main()
{
int n;
scanf("%d",&n);//输入输入元素的个数
for (int i = 0; i < n; i++) scanf("%d",&q[i]);
quick_sort(q, 0, n - 1);
for (int i = 0; i < n; i++) printf("%d ", q[i]);
return 0;
}
需要注意的是:要注意边界问题,如当这个点取左边界l时,后面的分段就不能以i为分界点,要用j;反之同理;所以为了方便才统一将x取为(l+r)/2处的值,以j为分界点,避免失误;
可以将quick_sort()这个函数的过程记一记,方便以后的使用,使代码又美观又高效
(新人第一次发布,有什么不完善的地方欢迎指出,我都会虚心接受T_T)