排序算法之快速排序

快速排序的思想:

  分治法,将大问题分为若干个小的问题,解决小问题然后合成大问题的解

典型的快速排序的一般过程:

  1、在数组中找到一个数,一般选作数组最后一个数作为中轴数X

  2、以中轴数X作为中心,使用一次划分partition,使得中轴数左边的数都比X小,右边的数都比X大,换句话说经历过一次划分后,中轴数X处在它本来应该在的位置上

  3、递归调用partition,最后使得整个数组有序

一次划分partition过程:

 1 int partition(int data[],int start,int end){
 2     int i=start-1;   
 3     int j=start;
 4     int x=data[end];
 5     for(;j<end;j++){
 6         if(data[j]<x){
 7             ++i;
 8             exchange(data+i,data+j);
 9         }
10     }
11     exchange(data+i+1,data+end);
12     return i+1;      //i标识的是数组中值小于X的最大下标,i+1即指一次划分后X所在的下标位置
13 }

 递归调用的过程:

1 void quicksort(int data[],int start,int end){
2     if(start<end){
3         int index=partition(data,start,end);
4         quicksort(data,start,index-1);
5         quicksort(data,index+1,end);
6     }
7 }

注:函数的边界检查条件可以交付给上层调用函数来完成

 快速排序的时间复杂度分析:

  上述为了简便说明,总是选取待排序数组的最后一个元素作为中轴数,假设一种极端的情况,待排数组已经有序或者元素值全部相同,进行一次partition划分后,中轴数左右两边的元素个数分别是N-1,0,即每经过一次划分,就仅仅将一个数组元素放置在它应该在的位置上,剩余的N-1个数还需要继续排序,每次划分的时间复杂度为遍历一次待排数组所消耗的时间O(n)

  设整个排序的时间复杂度为T(n),则最坏的情况下,T(n)=T(n-1)+T(0)+O(n),可以递推得T(n)=O(n^2)

  算法的最佳时间复杂度,在最理想的情况下,每次划分总是将待排数组均衡划分,即一次划分完成后,中轴数左右两边的元素个数都是(N-1)/2,则其总的时间复杂度

  T(n)<=2*T(n/2)+O(n),T(n)=O(nlgn)

  算法的平均时间复杂度,T(n)=O(nlgn),(任何一种按常数比例进行的划分都会产生深度为O(lgn)的递归树,每一层的时间复杂度为进行一次划分的时间O(n),所以总的时间复杂度是O(nlgn)----算法导论),可以理解为,如果某一层的划分效果比较差,则该层下面的划分可能会比较好,好差划分随机的分布在递归树的各层,总的划分渐进于每层都是情况好的划分。

快速排序的稳定性:

  由快排的三个过程可以知道,快排不是一种稳定的排序,例如[2,5,6,4(1),7,3,8,4(2)],经历一次划分后,数组变为[2,3,4(2),4(1),7,5,8,6],括号标识第1和第2个4.

快速排序的改进:

  快速排序对于输入数组的随机性有要求,如果待排序的数组元素具有较大的随机性,则排序效果接近于基于比较的排序方法的下限O(nlgn),如果输入的数组基本有序,则不适用于快速排序。

  因此,对于待排序数组,可以给出快排的随机化版本,每次在划分之前,在数组中随机选择一个数T和数组中最后一个数X交换位置,交换过后调用上述partition函数,从而将随机选择的元素T作为中轴数,从而优化排序的性能。

参考资料:《算法导论》

 

转载于:https://www.cnblogs.com/sjinsa/p/4741114.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值