• 快速排序


    概念引入

    快速排序顾名思义就是比较快速的排序(好吧的确是废话)
    快速排序的主要实现原理其实是分治(如果不知道分治是啥的小朋友可以近似的理解为低配版二分)
    选定一个基准 然后将比基准小的数都放在基准左边 比基准大的数都放在基准右边 (基准的位置确定了)
    然后分别对基准左边的序列和基准右边的序列进行快速排序(分治)直到整个序列有序
    平均情况下需要(log_n)轮 所以时间平均复杂度应该是(nlog_n) 但是如果我们每次恰好选定的基准选到了最大值(那你可真是倒霉) 那我们每次只能确定基准一个在最终序列中的位置, 最终的时间复杂度仍然是(n^2)
    关于如何选择基准和如何移动数字 我们会在下面的章节中讲到

    基准的选择

    一般来说可以随机选择基准:选择序列的最左边或者最右边都行 ,但是刚才我们已经分析过最差的时间复杂度会是(n^2),如果出题人丧心病狂的让你把一个完全逆序的序列排成一个升序,那我们只能(n^2)了,所以我们一般会随机选取一个数
    如果是用随机函数的话,又太过麻烦,如果用一个自己写的函数去选,又可能会影响到快排的效率(快排是(nlog_n)结果你写了一个(n^3)的随机选数 那宁可真是个小机灵鬼
    这里提供一种方法叫做三数中值法,即选择序列中间的数,最左边的数,最右边的数,然后取三个数的平均数来作为基准(如果出题人心理正常的话应该就不会卡你了

    算法实现

    主要的实现方法有两种: 挖坑法和指针法 一般来说指针法使用较为广泛
    首先来看挖坑法:

    • 现在给定一个序列a[] = 4,7,6,5,3,2,8,1 要求将其按升序排序
    • 现在来整个图

      首先,我们选定基准元素Pivot,并记住这个位置index,这个位置相当于一个“坑”。并且设置两个指针left和right,指向数列的最左和最右两个元素:

      接下来,从right指针开始,把指针所指向的元素和基准元素做比较。如果比pivot大,则right指针向左移动;如果比pivot小,则把right所指向的元素填入坑中。

    在当前数列中,1<4,所以把1填入基准元素所在位置,也就是坑的位置。这时候,元素1本来所在的位置成为了新的坑。同时,left向右移动一位。

    此时,left左边绿色的区域代表着小于基准元素的区域。

    接下来,我们切换到left指针进行比较。如果left指向的元素小于pivot,则left指针向右移动;如果元素大于pivot,则把left指向的元素填入坑中。

    在当前数列中,7>4,所以把7填入index的位置。这时候元素7本来的位置成为了新的坑。同时,right向左移动一位。

    此时,right右边橙色的区域代表着大于基准元素的区域。

    下面按照刚才的思路继续排序:

    8>4,元素位置不变,right左移

    2<4,用2来填坑,left右移,切换到left。

    6>4,用6来填坑,right左移,切换到right。

    3<4,用3来填坑,left右移,切换到left。

    5>4,用5来填坑,right右移。这时候left和right重合在了同一位置。

    这时候,把之前的pivot元素,也就是4放到index的位置。此时数列左边的元素都小于4,数列右边的元素都大于4,这一轮交换终告结束。

    • 指针法:
      仍然是刚才的序列a[] = 4,7,6,5,3,2,8,1 要求将其按升序排序

    开局和挖坑法相似,我们首先选定基准元素Pivot,并且设置两个指针left和right,指向数列的最左和最右两个元素:

    接下来是第一次循环,从right指针开始,把指针所指向的元素和基准元素做比较。如果大于等于pivot,则指针向左移动;如果小于pivot,则right指针停止移动,切换到left指针。

    在当前数列中,1<4,所以right直接停止移动,换到left指针,进行下一步行动。

    轮到left指针行动,把指针所指向的元素和基准元素做比较。如果小于等于pivot,则指针向右移动;如果大于pivot,则left指针停止移动。

    由于left一开始指向的是基准元素,判断肯定相等,所以left右移一位。

    由于7 > 4,left指针在元素7的位置停下。这时候,我们让left和right指向的元素进行交换。

    接下来,我们进入第二次循环,重新切换到right向左移动。right先移动到8,8>2,继续左移。由于2<8,停止在2的位置。

    切换到left,6>4,停止在6的位置。

    元素6和2交换。

    进入第三次循环,right移动到元素3停止,left移动到元素5停止。

    元素5和3交换。

    进入第四次循环,right移动到元素3停止,这时候请注意,left和right指针已经重合在了一起。

    当left和right指针重合之时,我们让pivot元素和left与right重合点的元素进行交换。此时数列左边的元素都小于4,数列右边的元素都大于4,这一轮交换终告结束。

    以上就是快速排序的一般思路 (sort大法好) 虽然现在有现成的sort可以用但是快排的思想还是要掌握的

    点个关注>.)<

    以上插图及过程参考博客

  • 相关阅读:
    geoserver发布地图服务WMTS
    geoserver发布地图服务WMS
    geoserver安装部署步骤
    arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)
    cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)
    arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
    arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
    arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  • 原文地址:https://www.cnblogs.com/2004-08-20/p/13257609.html
Copyright © 2020-2023  润新知