关于高效排序算法Quick Sort的原理解释及其在C语言上的实现

这篇博客介绍了快速排序算法的原理,包括分治法和递归的应用,详细阐述了算法基本思想、基准数字的选取以及如何利用i, j指针进行排序。通过C语言代码展示了快速排序算法的实现过程,同时提到了算法的时间复杂度,指出其效率在最好和最坏情况下有所波动。" 126782874,8396369,SystemVerilog 控制流:深入理解 forever 循环,"['数字IC', 'SystemVerilog', '硬件描述语言', '验证']
摘要由CSDN通过智能技术生成

序言

笔者还只是大一新生,在做我们学校OJ平台上的题的时候遭遇了排序算法太慢而导致TLE(Time Limit Exceed,即超时)错误,于是上网查询了很多资料了解了快速排序算法。在学习该算法之后,由于觉得该算法实在是太厉害,于是突发奇想在CSDN上写了一篇小文章。
这是笔者第一次发表作品,内容肯定不够详尽,也肯定不够完美,请大佬们看了之后轻喷。

介绍1

快速排序法是对冒泡排序的一种改进算法,由C·A·R·Hoare2在1960年提出。该算法通过将数组分割为使得两边数字分别小于中间的数字和大于中间的数字,并将这种过程通过递归进行多次,使数组中的元素最终被调整为有序数列。

原理

下面将会介绍快速排序算法的原理。在进入正式的解释前,我们需要先了解快速排序法涉及到的两种计算机编程技巧

补充内容

分治法介绍3

首先介绍分治法。分治法是计算机科学中的一种重要编程技巧。其基本思想在于将一个大问题拆分为小问题,当把小问题一个个地解决完成后,把小问题的结果结合起来大问题便被解决了。
分治法是很多高效算法的基础,比如本文正在介绍的快速排序算法,以及另外一种排序算法归并排序法,快速傅里叶变换等等。

递归介绍4

其次再介绍递归。同分治法一样,递归也是计算机科学中的一种重要编程技巧。递归实际上就是在一个函数运行过程中调用了该函数本身。不过为了保证该函数运行会有终止的时候,在运用了递归的函数之中都会加入一些边界条件以保证函数运行到一定程度会终止。

快速排序算法基本思想

快速排序算法的基本思想:将待排序数组中的一个数字作为基准数字(Key)。此后,将比基准数字小的数字移动到基准数字的左边,比基准数字大的数字移动到基准数字的右边。这一步骤完成后,整个数组将会变为中间是基准数字,其左的数字都比基准数字小,其右的数字都比基准数字大。通过这种方法,该算法将数组分割为了更小和更大的部分,此后通过递归的方法,将左边和右边的部分再进行同样的操作,直到数列中的数字已经有序。这时一个大型的数列排序便被完成了排序

基准数字的选取

在快速排序算法中,我们往往将送入算法中的数组最右边的数字作为基准数字。但是为了避免遇到一个有过多重复数字堆砌在一起的数组,使得算法效率被迫降低到 O ( n 2 ) O\left(n^{2}\right) O(n2),因此在一些更优化的快速排序算法中会使用随机数作为索引值在数组中挑选一个数字作为基准值进行排序。不过在本文中,笔者为了使文章尽可能让大家理解,就直接选取最右边的数字作为基准数字了。

利用i,j作为指针对数组进行检索和排序

将最左边的索引值作为i,最右边的索引值(对应的是基准值)作为j。首先是i向右移动,分别查看其所指向的元素与基准值的关系,如果左边的数字小于基准值则i继续右移,否则将i所指向的元素与j所指向的元素(及基准值)交换。交换后,i所指向的元素变为了基准值,此时改为j向左移,与i移动时相似,当遇到j所指向的元素大于基准值则j继续左移,否则交换数字并改为i移动。当i和j相遇时结束
如此方法继续下去,数组将会变为以基准值为中心,左部分比基准值低,右部分比基准值高。
通过i,j移动对数组进行排序在C语言中可以如下代码那样进行:

int dir = 1;//用于指示该那一个标记动
    while(i != j)
    {
   
        if(dir == 1)
        {
   
            if(a[j] < a[i])//当右边发现有小于基础数字的数字时两边交换
            {
   
                int t = a[j];
                a[j] = a[i];
                a[i] = t;
                dir = 0;//交换过后换为左方标记动
            }else {
   
                j -= 1;
            }
        }else{
   
            if(a[i] > a[j])//当左边发现有大于基础数字的数字时两边交换
            {
   
                int t = a[i];
                a[i] = a[j];
                a[j] = t;
                dir = 1;//交换过后换为右方标记动
            }else{
   
                i 
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值