001基础算法:快速排序
在算法里面最常见的应该就是排序了吧,第一次让我感受到算法的快感的是排序,可以极大的提到我们代码的执行效率.
下面我将逐一分享我对排序算法的认识和理解,顺便会附加相应的例题和算法模板~
靓丽的风景照~
下面为正文部分
快速排序
- 实现原理
- 确定分界点
快速排序的本质思想是分治,首先,如上图所示,我们将一组数记录三个点,分别为l(最左边)和r(最右边)的点(必须),;以及这一组数中任意一点(不固定,可以是随机一个数字,只是比较建议取位置中间的数字作为第三个点). - 调整范围(难点)
在这里我们确定的随机数字的值为x,我们以x为分界点,通过遍历数组,让分界点左边的数值≤x,分界点右边的数值>=x,由此,可以将这组数字进一步有序化. - 递归处理左右两段
顾名思义,既然是递归,就是将前两步的操作进行反复执行,左边不断有序,右边也不断有序,排序到最后把所有数按照顺序排列起来
其数值就会实现完全有序!
代码模板:
void quick_sort(int q[],int l,int r)
{
if(l>=r) return;
int x=q[(l+r+1)/2],i=l-1,j=r+1;
while(i<j)
{
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j) swap(q[i],q[j]);
}
quick_sort(q,l,i-1);
quick_sort(q,i,r);
}
这段代码无需多言,非常优雅,是我见到过的,在快排里面非常优雅的代码
与以往暴力做法不同,这个模板无需开辟新的空间,因为其核心思想额外增加了两个指针i,j
i,j从数组两头向中间遍历,当指针i与j相遇,则视为完成一次递归,相当优雅,下面给出完整代码
完整代码
#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;
int x=q[(l+r)/2],i=l-1,j=r+1;
while(i<j)
{
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j) swap(q[i],q[j]);
}
quick_sort(q,l,i-1);
quick_sort(q,i,r);
}
int main()
{
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]);
}
这段代码实现以下功能:
你先输入一个你想要排序数组的个数,然后输入对应个数的数字,即可得到从小到大排列的有序数组
当然,如果你希望获取一串从大到小的数组也是可以实现的,只需将
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j) swap(q[i],q[j]);
改为:
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j) swap(q[i],q[j]);
即可