内部排序之快速排序(巨详细!!!)

快速排序

  • 简介

快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R. Hoare 在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

  • 基本思想
    1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
    2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
    3)此时基准元素在其排好序后的正确位置
    4)然后分别对这两部分记录用同样的方法继续进行排序(递归),直到整个序列有序。
  • 图解
    首先设置一个基准点paivot,一个left指针和一个right指针,如图所示:
    left指针用于寻找比基准值大的数,right指针用于寻找比基准值小的数

step1. 从右指针right开始向左移动(这个很重要,必须从右指针开始移动,下面再给出解释),当找到一个比基准值小的时候停止移动。
在这里插入图片描述
step2. 左指针left开始移动,当找到一个比基准值大的时候停止移动。
在这里插入图片描述
step3. 交换左右指针所指的值。
在这里插入图片描述
step4. 重复1、2、3步,直至left不等于rightleft != right时,停止,然后交换基准值和两个指针所同时指向的值。此时基准值右边全是大于它的数,左边全是小于它的数。
在这里插入图片描述
step5. 再分别对基准值左半部分和右半部分进行上述步骤,直至推出循环。
下面的步骤大同小,大家可以可以自己去画一下,还能帮助理解。
在这里插入图片描述

  • 代码实现
public static void quickSort(int[] arr,int left,int right){
        if (left > right){//递归的退出条件
            return ;
        }
        int temp = 0;
        int paivot = left; //基准点
        int base = arr[paivot]; //base用于保存基准值,便于下面的交换
        int i = left, j = right;
        while(i != j){
            //右指针移动
            while(arr[j] >= base&& i < j){
                j--;
            }
            //做指针移动
            while(arr[i] <= base&& i < j){
                i++;
            }
            if (i < j){
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        //交换基准点的值
        arr[left] = arr[i];
        arr[i] = base;
        //递归
        quickSort(arr,left,i-1);
        quickSort(arr,i+1,right);
    }
  • 注意
    还记得我们在上面留下了一个问题,大家可以想一下为什么不能先移动左指针,而一定要先动右指针。接下来给大家解释一下,我在网上也看到了好多的解释,但是还是觉得不是很直观,有点模棱两可,所以我先解释然后用图解的方式演示一遍。
    原因:先移动右边的指针是为了保证每次推出循环,和基准点的值做交换的那一个数据,一定是小于基准值的,而要是先移动左指针效果就不一定是那样了,语言不好理解,我们直接用图解来看一下。
    先移动左指针:如图左指针停下来了
    在这里插入图片描述
    再移动右指针:此时右指针没动,因为2小于3
    在这里插入图片描述
    交换,然后在去移动,然后再交换:
    在这里插入图片描述
    注意马上就要出错了: 重复上述步骤,此时指针位置如图:
    在这里插入图片描述
    看上图,可知两个指针已经相等了,应该退出循环,交换基准值了,但是大家发现没有此时指针所指的数据为 6,如果交换之后它位于3的左边如下图,是不符合快速排序的规则的(基准值左边的数比它小,右边比它大)
    在这里插入图片描述
    这也就是为什么一定要先移动右指针的原因,大家一定要注意,此处不能去创新。
  • 总结
    学习排序算法是一个很有趣的过程,大家在学习过程当中一定要多想,不能光看,多动手,多敲键盘,画图也是对于学习算法的一个重要手段,谢谢你们的阅读,希望大家相互学习,共同成长。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值