zoukankan      html  css  js  c++  java
  • 记录快排相关-快速排序、快速选择Topk。快速排序的优化-Python

    关于排序的一些想法

    实际上从实用的角度看,排序的那么多分类标准似乎只有复杂度、场景、以及稳定性的对于重应用的程序员比较有意义,除了把所有排序通讲

    之外,把比较常出现的能够扩展的排序方法都单独写一个Blog,快排、堆排、二分、以及Timsort

    快排实际上就是三个步骤

    1. 挑选排序的基准
    2. 划分为比基准大小的左右两部分
    3. 递归的求解左右子数组

    这里其他语言第二步还比较麻烦,把基准的坑腾出来进行划分,Python中可以直接用列表表达式写出来,还是比较简洁的

    再说到快排本身  实际上这就是一个递归求解的多叉树,什么时候把所有叶子分清楚了就结束了,如下图

     实际上每一层具体的时间复杂度只可能等于n,时间复杂度完全取决于树高,树高则取决于你的左右子树每层的工作量

    比如某一层,左子树只处理了一个数字(也就是只有一个数比基准小),那他就会耽误进度,让递归树变高,甚至退化成链表,

    也就是待排序列nums是升序的或者是降序的。

    所以最好情况是O(nlogn) 最坏是O(n^2)

    关于Topk的快速选择

    Topk是一个选出数组中第k大/小的问题

    Topk一般排序解法有两种,快选和推排序,这里我们正好说一下快排进化来的快选

    快排是每层总是n的工作量,以此在递归树中完成整个数组的排序,而快速选择则不需要,我们只要找出Topk即可,也就是左右数组我们只留一个

    [7,2,14,4,6,8,12,19],要找第3个也就是6

    这时候比如以7为基准,[2,4,6]  [14,8,12,19]快排需要左右都完成,而快选是只要左边就可以,因为len(left)>= k也就是3,右边不需要了,

    所以复杂度是O(n+n/2+n/4...+1)实际上还是On

    关于快速排序的优化

    实际上快排效率差的大多两种情况

      1.升序降序序列

      2.重复值

      3.小数组快排效率不如插入

    针对这些情况有以下几种优化方案

    1.随机化选择基准

    这个计算机算法设计与分析这本书上讲过几种随机化算法,随机选择基准来消除总是选择num[0]带来的升序降序数组退化成On^2的情况

    但实际上消除不了,而是大大降低了这种概率 

    2.三数取中选择基准

    这样基本消除了升降序的问题

    3.当快排进行到一定大小,改用插入排序)

    4.额外处理相同元素,【1,22,3,3,3,5,7,8】比如宣到3为基准,其实会影响效率,而当全部都是3时,效率会急剧下降,所以对与基准重复的数字不再放入左右数组

     这是一张效率图,参考自https://blog.csdn.net/insistgogo/article/details/7785038

    里面有各种版本的代码,有兴趣的同学可以看看

  • 相关阅读:
    【t034】Matrix67的派对
    【t042】炮击坦克
    Multiple address space mapping technique for shared memory wherein a processor operates a fault handling routine upon a translator miss
    阿里云平台
    OpenShift:外国的免费云平台
    注册亚马逊云服务
    腾讯云
    微信公众号免费进行开发者中心云服务器配置
    消息的接收与响应
    那个学完这个小程序创业课程的小白现在月入17万
  • 原文地址:https://www.cnblogs.com/handso/p/13697220.html
Copyright © 2011-2022 走看看