算法简介:

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。

步骤为:

  1. 挑选基准值:从数列中挑出一个元素,称为“基准”(pivot),
  2. 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成,
  3. 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。

递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。

选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。

 

时间复杂度:

最好情形:

    数学归纳法推导:

  1. T(n)≤ 2T(n/2) + n,T(1)= 0  
  2. T(n)≤ 2(2T(n/4)+ n/2) +n = 4T(n/4)+ 2n  
  3. T(n)≤ 4(2T(n/8)+ n/4) +2n = 8T(n/8)+ 3n  
  4. T(n)< 8(2(T(n/16)+ n/8)+3n = 16T(n/16)+ 4n  
  5. ……  
  6. T(n)≤nT(1)+(log2n)×n= O(nlogn) 

    理解:

如下图,最优情况下,每次找到的参考轴把数据分成均匀的两半,最后应该是一个平衡二叉树状态;二叉树的层数(logn)即为递归需要进行的次数,并且每轮递归结束时,都将二叉树遍历了一遍(n),所以最优的情况下,时间复杂度为O(nlogn)

                                                          

最坏情形:

       最坏情形下,为正序或逆序排列,二叉树画出来应该是一棵斜树,并且需要经过n-1次递归调用才能完成,且第i次划分需要经过n‐i次关键字的比较才能找到第i个记录,也就是枢轴的位置,所以:

                                                             

     最终的时间复杂度应该O(n2)

 

平均复杂度:

枢轴可以随机的在第k的位置(1≤k≤n):

                   

 n-1是分割所使用的比较次数。因为基准值是相当均匀地落在排列好的数列次序之任何地方,总和就是所有可能分割的平均。

这个意思是,平均上快速排序比理想的比较次数,也就是最好情况下,只大约比较糟39%。这意味着,它比最坏情况较接近最好情况。这个快速的平均运行时间,是快速排序比其他排序算法有实际的优势之另一个原因。

 

 

空间复杂度

       空间的消耗主要是递归造成的栈空间使用,最好情况,递归树的深度为log2n,其空间复杂度也就为O(logn),最坏情况,需要进行n‐1递归调用,其空间复杂度为O(n),平均情况,空间复杂度也为O(logn)。

 

 

 

参考:

https://blog.csdn.net/weshjiness/article/details/8660583

https://zh.wikipedia.org/zh/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐