快速排序

最近用sort函数比较多,发现现在都不会手写快排了(丢人),这里来复习顺便尝试讲解下。这是参考《啊哈算法》上的例子写的,因为我懒得找例子了。

快排原理

快排核心是一种跳跃式的比较大小,从而时间复杂度较低。
首先我们看到这个数组

0123456789
61279345108
第一轮探测

下标从0开始,我们选取一个基准数a[0]=6,然后我们从右边界用j为下标开始找,找第一个小于基准数6的,当然是下标为7的时候的5。然后我们从左边界用i作为下标开始找,找第一个大于基准数6的数,当然是下标为3的时候的7了。

0123456789
61279345108

此时我们的i还是小于j的,那么我们交换这两个地方的位置。

0123456789
61259347108

然后我们继续从右边开始,与之前步骤一样的

0123456789
61259347108

继续交换位置

0123456789
61254397108

然后j继续向左寻找基准数小的数,于是j=5的位置停下来了。然后i开始向右寻找比3大的数,但是此时I与j相遇了,在 i 与 j 相遇的时候我们将基准数与此时的相遇点的数交换。

0123456789
31254697108

第一轮探测已结束
大家可以看到,其实总结起来,就是

  1. 先找到基准数,一般我们把第一个取为基准数。
  2. 开始时我们将 i 指向数组最左边(0),j指向数组最右边。
  3. 因为这个时候设置的基准数是最左边的数,那么我们要从最右边 j 开始往左边搜索第一个比基准数小的数;然后出动 i ,从左边寻找第一个比基准数大的数,找到之后交换两者位置。
  4. 若 i 与 j 未相遇,那么就继续执行第三步。若 i 与 j 相遇便终止,交换基准数与相遇点。
第二轮探测

此时我们以上一轮的基准数为分界点拆成两个序列,左边的很明显我们可以知道是

01234
31254

然后我们与第一轮探测一样的,此时我们直接得出结果

01234
21354

此时3已经归位,接下来处理3左边的序列与右边的序列。

总结

快排的思路就是将每一次的基准数归位,直到所有的数都归位,那么排序也就完成了。
两天前写的新鲜的快排模板

#include <cstdio>
#include <algorithm>
using namespace std;
int a[200010];
void quicksort(int left,int right)
{
    int mid=a[(left+right)/2];
    int i=left,j=right;
    do
    {
        while(a[i]<mid)
        {
            i++;
        }
        while(a[j]>mid)
        {
            j--;
        }
        if(i<=j)
        {
            swap(a[i],a[j]);
            i++;
            j--;
        }
    }
    while(i<=j);
    if(left<j)
        quicksort(left,j);
    if(i<right)
        quicksort(i,right);
    return;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        quicksort(1,n);
        for(int i=1; i<=n; i++)
        {
            printf("%d ",a[i]);
        }
        printf("\n");
    }
}

如果你觉得你快排啥的都会了,那么我们就可以学一个c++的sort函数了。
用法:

for(int i=0;i<n;i++)
	scanf("%d",&a[i]);
sort(a,a+n);

他初始排序是从小到大的排序,而如果要改变成从大到小的排序,就需要重写cmp函数。
然后这个sort函数还比较好用的地方在于,他可以比较结构体中元素的大小。

#include <cstdio>
#include <algorithm>
using namespace std;
struct kuailefengnan
{
    int x;
    int y;
}q[1100];
bool cmp(kuailefengnan a,kuailefengnan b)
{
    return a.x>a.y;
}
int main()
{
    for(int i=0;i<10;i++)
    {
        scanf("%d %d",&q[i].x,&q[i].y);
    }
    sort(q,q+10,cmp);
}

重写就和上面的cmp一样。

后记

这里提及sort函数是因为他是一种类似于快排的排序,如果你快排掌握熟练了,可以直接使用sort函数减少敲代码时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值