快速排序算法的原理:
快速排序是一种对冒泡排序进行改进的算法,其基本算法思想是基于分治的。可以简单理解为,在待排序数组中选取一个基准点(也可以说是分界点),使基准点左边的数是小于等于基准点的,且基准点右边的数是大于基准点的,同时使用递归的方式对基准点左右两边的数组进行排序,使得数组整体有序,快速排序算法的详细流程如下:
- 从需要排的数中随便选取一个数作为基准点x(分界点);假设所要排的数是从l到r,即数组是q[l~r],有三种常用确定分界点x的方法:q[l],q[(l+r-1)/2],q[r];
- 根据上面的基准点,调整区间,使得x左边区域内的数都小于等于x,x右边区域内的数都大于等于x;:
- 递归处理左右两段区间。(只要左右两端区间都排好序了,那么整体就排好序了)
其中步骤二应该是快速排序算法中的重难点,在此给出两种步骤二的实现过程:
- 创建a[]、b[],对于q[l~r],q[i]小于等于x的数放到a[],q[i]大于x的数放到b[]中,然后先把a[]的数放入q[]中,再把b[]中的数放入q[]中,但是这种方法较为暴力
- 另一种方法是在q[l~r]两端点分别放置指针i还有指针j,若指针i当前所指的数小于等于x,指针i则向前进一,反正则停止,若指针j当前所指的数大于x,则指针j向前进一,反之停止,直到两指针重合为止;若两指针同时停止,则交换两指针所指的数,并同时往前移动一格。实际上不管指针所指的数同基准点x比较的结果如何,指针总要先向前(向后)进一的。
代码实现:
//C++方式实现
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n;
int q[N]; //定义了待排数组的容量
void quick_sort(int q[], int l ,int r) //快速排序算法的实现过程
{
if (l >= r) return; //判边界,如果区间内只有一个数或者没有数则直接return
int x = q[(l + r + 1) / 2], i = l - 1, j = r + 1; //确定分界点(随机),在这里是q[(l + r + 1) / 2],然后确定指针所在位置
while(i < j)
{
do i ++ ; while(q[i] < x); //因为指针向前进一时候是先向前,再同x进行判断,所以使用do...while语句
do j -- ; while(q[j] > x);
if(i < j) swap(q[i], q[j]); //交换指针i和j所指向的数; 若没有swap函数,可以用下列语句进行交换:if(i<j){int t = q[i];q[i]=q[j];q[j]=t}
}
quick_sort(q, l , j); //对左右两边数组进行递归排序,左右数组是对称的,一端是(q,l,j),另一端则是(q,j+1,r)
quick_sort(q, j + 1, r); //相对应的,一段是(q,l,i - 1),另一端是(q,i,r)
}
int main(){
scanf("%d",&n); //由于读入数据过大,使用scanf进行读数据会更好,相较于cin会更快些
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;
}