详解快速排序(附代码)

前言

快速排序是程序员必须掌握的一种算法,学习快排重要的是要汲取快排里边的二分思想,很多复杂的算法都有二分的影子, 很多人对快速排序有有恐惧,认为快速排序很难,我相信你在看完这篇文章后,能够对快排有一个新的认识,现在快排算法在经过前辈的进化与修改已经变的非常简短,不管怎样, 我们都还是要认真的学习,对吧~

主要思想及思路

刚才在前言说过快排主要是利用二分的思想,即选择一个基准数(基准数就是数组里随机的一个数字,只是给他起了一个难懂的名字,显得非常难而已,当然你也可以叫他数组随机数~),将数组一分为二, 数组的一边全部是小于基准数的,而另一边全部大于基准数,进而对分成的两个数组继续继续上述的行为,直到分成一个个小数组中只剩下一个数, 这时候快速排序也完成他的使命, 什么, 不够形象?那我来画个图对每一步进行剖析~
在这里插入图片描述
这里是十个乱序数字,我们来模拟我们的上述步骤:
首先先选择一个基准数(基准数就是选当前数组的一个数)当然这个基准数可以是数组里随机的数字,这里我们当然也可以选择数组最中间的数字,即‘6’作为基准数(大家要注意了这个基准数是随数组变化而变化的哦,下边我会介绍到),接下来我们对数组进行分割,在这里不少同学犯了难, 这里该怎样进行操作呢,哈哈,这里其实也涉及到一个小小的技巧, 叫双指针技巧(又是一个唬人的叫法),是一个重要的技巧,好了,不和大家卖关子了,让我来设置两个“警察”把站位不对的小朋友揪出来。
在这里插入图片描述
好啦, 两个“警察”我给设置好了,他们分别设置在数组的两端,负责队伍中检查,还记得我们的基准数吗,没错是‘6’,首先绿警官开始检查第一个数字,查看了第一个小朋友的身份证, 发现数字是3, 比数字6小,“嗯,很好”,于是开始检查下一个数字7,发现数字7比数字6大,这可不对,这赶紧给蓝警官打电话,蓝警官接到消息赶紧排查,蓝警官检查的第一个数字是‘1’,一下子就找到了,于是两个警官把两个小朋友给交换过来变成了这样(顺势两个警官都进了一格)⬇
在这里插入图片描述
俩个警官继续排查,重复上边的过程,我把每一步的过程给大家列出来:

在这里插入图片描述

这里完成了8和4的交换(两个警官顺势进一格)⬆
在这里插入图片描述
两个警官经过辛苦的工作,蓝警官跑到了绿警官的前边,第一次搜查完成,接下来对3 1 9 4 2 5 与 6 8 10 7两个小组进行上述的搜查,(这里注意下,对着这两个小组进行搜查的时候是不是要选择当前小组的一个数字当作基准数呢,答案是肯定的吧)直到分到每个小组都只剩下一名小组成员。
顺便说一下这两个警察搜人的方式就是双指针技巧,科学家有时就是这样,往往名字很文艺,但又有多少是内容是非常困难呢~

代码实现(纯C)

这里学习快排的应该都是刚接触语言的同学, 所以选择的C语言,下面我在代码里进行代码分析。

#include<stdio.h>
#define max 100010 //这是我之前做过的一个算法题,很适合用快排~
int a[max];//首先定义一个数组来存储数字~
void  q_sort (int l, int r)//这里两个参数分别是数组的边界,也就是蓝警官与绿警官开始检查的位置
{
    if(l >= r)//这个作为函数结束递归的条件
    return;
    int x = a[(l + r + 1) / 2];//这个变量 x 是上边说的基准数~
    int right = r + 1;//这里定义两个变量分别代表蓝警官与绿警官
    int left = l - 1;//什么?为什么要- 1(同上边 + 1)? 这里其实要配合下边的do while{} 疑惑的请继续往下看~
    while(right > left)//(判断蓝警官与绿警官是否相遇过)相遇就结循环
    {
        do
        {
            right --;
        } while(a[right] > x);//这里就是警官搜人的过程啦,符合标准就能通过警官的检查!
        do
        {
            left ++;
        } while (a[left] < x);
        if(right > left)//确保警官搜到的人交换之前两个警官没遇到过~
        {
            int temp = a[right];
            a[right] = a[left];
            a[left] = temp;
        }
    }
    q_sort(left, r);//这里就是将分成的小数组重复上述过程。
    // 这里注意一下边界问题, 可以试试将left改成right 检查下运行情况,以及如何修改才能正确,感兴趣的同学可以试试~
    q_sort(l, left - 1);
    
}
int main()
{   
    int n;
    scanf("%d", &n);
    for(int i = 0 ; i < n; i ++)    scanf("%d", a + i);
    q_sort(0 , n - 1);
    for(int i = 0;i < n; i ++)    printf("%d ", a[i]);
    return 0;
}

结语

写到这里就结束了,快排的思想可以解决一些问题,比如找到第 k 个数字 等等,这个大家可以在网上找题目进行训练, 希望这篇文章能够帮助大家 , 有错误的地方欢迎大家指正批评~

发布了1 篇原创文章 · 获赞 2 · 访问量 134

猜你喜欢

转载自blog.csdn.net/weixin_45630535/article/details/104171964