回顾快排

快速排序,面试必问题。面试百度时三次面试被问到快排,本以为掌握的很好,但细节方面还是不到位,发挥的不是很好,特此记录,勉励自己。

问题:为什么是nlog(n),n怎么来,log(n)怎么来

快速排序
快速排序是应用最广泛的排序算法,基本思路是:将一个数组分成两个子数组,将两部分独立排序,当两个子数组都有序时,整个数组也就有序了,这与归并排序有所不同,归并排序中,将一个数组分成两个数组后,需要对两个子数组进行归并,在归并的过程中排序,而快速排序是在将一个数组分成两个数组的过程中进行排序,当分到尽头的时候,数组就已经有序了,不需要再进行其它任何操作
快速排序中重点是找到将一个数组分为两个数组的切分点,在归并排序中,其实也是有这样的切分点的,就是 mid,也就是说归并排序默认将一个数组等分,而在快速排序中,对一个数组的切分,并不一定是等分,需要根据具体的切分点的位置来进行切分,所以,找到合适的切分点的位置是很重要的,直接影响到整个排序的性能。
寻找切分点
切分点需要满足三个条件:(假设切分点索引为 k)
对于某个索引 k,数组中对应索引的值 a[k] 是确定的
数组索引[lo,k-1] (即切分点左边的所有元素) 中的所有元素的值都不大于切分点元素的值( <= )
数组索引[k+1,hi] (即切分点右边的所有元素) 中的所有元素的值都不小于切分点元素的值( >= )

假设有一组数:


寻找切分点的过程是:(其中 lo 为数组最低位索引,hi 为数组最高位索引,从左往右遍历的指针为 i,从右往左遍历的指针为 j)
取 a[lo] 的值作为初始切分点元素的值,即切分点索引为 0,值为 16

从数组左端向右遍历[1,5],当遇到一个大于等于切分点的元素,即索引为 2 的元素,停止遍历,此时 i=2

从数组右端向左遍历[5,0],当遇到一个小于等于切分点的元素,即索引为 5 的元素,停止遍历,此时 j=5

交换 i 和 j 对应的值,交换后:


从数组左端向右遍历[3,5],当遇到一个大于等于切分点的元素,即索引为 5 的元素,停止遍历,此时 i=5

从数组右端向左遍历[4,0],当遇到一个小于等于切分点的元素,即索引为 4 的元素,停止遍历,此时 j=4

当 i>=j 时停止循环,不会执行 i 和 j 的交换,而是将切分点元素和 j 元素交换,交换后:

到此,寻找第一个切分点完成,切分点索引为 4,对应的值为 16
找到切分点,接下来将数组按照切分点分成两部分,从上面的执行结果可以知道,数组将被分为 [0,3] 和 [5,5],接下来就是对 [0,3] 部分重复寻找切分点的过程:
取 a[lo] 的值作为初始切分点元素的值,即切分点索引为 0,值为 14


从数组左端向右遍历[1,3],当遇到一个大于等于切分点的元素,没有找到,遍历到数组尽头,此时 i=3

从数组右端向左遍历[3,0],当遇到一个小于等于切分点的元素,即索引为 3 的元素,停止遍历,此时 j=3

当 i>=j 时停止循环,不会执行 i 和 j 的交换,而是将切分点元素和 j 元素交换,交换后:

到此,寻找第二个切分点完成,切分点索引为 3,对应的值为 14

同理,数组将按照切分点分为 [0,2] 和[3,3],接下来对 [0,2] 部分重复寻找切分点:
取 a[lo] 的值作为初始切分点元素的值,即切分点索引为 0,值为 11


从数组左端向右遍历[1,2],当遇到一个大于等于切分点的元素,即索引为 1 的元素,停止遍历,此时 i=1

从数组右端向左遍历[2,0],当遇到一个小于等于切分点的元素,没有找到,遍历到数组起始位置,此时 j=0

当 i>=j 时停止循环,不会执行 i 和 j 的交换,而是将切分点元素和 j 元素交换,交换后:

到此,寻找第三个切分点完成,切分点索引为 0,对应的值为 11
此时,由于切分点位置为 0,所以只能切分出一个子数组,即 [1,2],继续寻找切分点
取 a[lo] 的值作为初始切分点元素的值,即切分点索引为 1,值为 13


从数组左端向右遍历[2,2],当遇到一个大于等于切分点的元素,没有找到,遍历到数组尽头,此时 i=2

从数组右端向左遍历[2,1],当遇到一个小于等于切分点的元素,即索引为 2 的元素,此时 j=2

当 i>=j 时停止循环,不会执行 i 和 j 的交换,而是将切分点元素和 j 元素交换,交换后:

到此,寻找第四个切分点完成,切分点索引为 2,对应的值为 12
数据已经有序了,整个过程中寻找了四次切分点

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,740评论 18 399
  • 最近在读< >时,了解到了很多常用的排序算法,故写一篇读书笔记记录下这些排序算法的思路和实现. 冒泡排序 冒泡排序...
    SylvanasSun阅读 710评论 0 0
  • 某次二面时,面试官问起Js排序问题,吾绞尽脑汁回答了几种,深感算法有很大的问题,所以总计一下! 排序算法说明 (1...
    流浪的先知阅读 1,205评论 0 4
  • 什么是产品经理 产品经理(Product Manager)就是企业中专门负责产品管理的职位,产品经理负责调查并根据...
    牧星银河阅读 2,028评论 0 9
  • 万事开头难,兴致满满的准备开始我的第一篇自我讨伐,却发现好像还是无从下手。或许还是想给自己留一点的脸面,不至于未来...
    ythyth8阅读 325评论 0 0