快速排序的思想

快速排序算法是基于分治策略的另一个排序算法。

该方法的基本思想是:

1.先从数列中取出一个数作为基准数,记为x。

2.分区过程,将不小于x的数全放到它的右边,不大于x的数全放到它的左边。(这样key的位置左边的没有大于key的,右边的没有小于key的,只需对左右区间排序即可)

3.再对左右区间重复第二步,依次递归下去,直到各区间只有一个数


//快速排序
int partTion (int *a ,int left ,int right)
{
// 找一个基准值放在最右边
int piont = a[right];
int index = left;
int  i;
//依次与基准值比较,小的与下标交换
for(i = left;i < right; i++)
{
if(a[i] < piont)
{
swap(a,index,i);
index ++;
}
swap(a,index,piont);  //比较完,交换基准值与下标,出现基础值左边都是比其小的,右边都是比其大的
}

return index; //返回基准值所在下标
}


void qsort (int *a,int left,int right)
{
if(left < right)
{
int pivot =partTion(a,left,right)
qsort(a,left,pivot);// 在讲基准值左边排序
qsort(a,pivot+1,right); //基准值右边排序
}
}


int main()
{
int a[10] = {1,3,4,53,5,3,5,4,3,34};
int len =sizeof(a)/sizeof(a[0]);

qsort(a,0,len-1);

printA(a,len);

return 0;
}

时间复杂度

        快速排序涉及到递归调用,所以该算法的时间复杂度还需要从递归算法的复杂度开始说起;
        递归算法的时间复杂度公式:T[n] = aT[n/b] + f(n)  ;对于递归算法的时间复杂度这里就不展开来说了;

最优情况下时间复杂度

         快速排序最优的情况就是每一次取到的元素都刚好平分整个数组(很显然我上面的不是);
        此时的时间复杂度公式则为:T[n] = 2T[n/2] + f(n);T[n/2]为平分后的子数组的时间复杂度,f[n] 为平分这个数组时所花的时间;
        下面来推算下,在最优的情况下快速排序时间复杂度的计算(用迭代法):
                                          T[n] =  2T[n/2] + n                                                                     ----------------第一次递归

                 令:n = n/2        =  2 { 2 T[n/4] + (n/2) }  + n                                               ----------------第二次递归

                                            =  2^2 T[ n/ (2^2) ] + 2n

                令:n = n/(2^2)   =  2^2  {  2 T[n/ (2^3) ]  + n/(2^2)}  +  2n                         ----------------第三次递归  

                                            =  2^3 T[  n/ (2^3) ]  + 3n

                ......................................................................................                        

                令:n = n/(  2^(m-1) )    =  2^m T[1]  + mn                                                  ----------------第m次递归(m次后结束)

               当最后平分的不能再平分时,也就是说把公式一直往下跌倒,到最后得到T[1]时,说明这个公式已经迭代完了(T[1]是常量了)。

               得到:T[n/ (2^m) ]  =  T[1]    ===>>   n = 2^m   ====>> m = logn;

               T[n] = 2^m T[1] + mn ;其中m = logn;

               T[n] = 2^(logn) T[1] + nlogn  =  n T[1] + nlogn  =  n + nlogn  ;其中n为元素个数

               又因为当n >=  2时:nlogn  >=  n  (也就是logn > 1),所以取后面的 nlogn;

               综上所述:快速排序最优的情况下时间复杂度为:O( nlogn )


最差情况下时间复杂度

        最差的情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了(每一次都排好一个元素的顺序)

     这种情况时间复杂度就好计算了,就是冒泡排序的时间复杂度:T[n] = n * (n-1) = n^2 + n;

     综上所述:快速排序最差的情况下时间复杂度为:O( n^2 )


平均时间复杂度

        快速排序的平均时间复杂度也是:O(nlogn)

空间复杂度

        其实这个空间复杂度不太好计算,因为有的人使用的是非就地排序,那样就不好计算了(因为有的人用到了辅助数组,所以这就要计算到你的元素个数了);我就分析下就地快速排序的空间复杂度吧;
        首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
     最优的情况下空间复杂度为:O(logn)  ;每一次都平分数组的情况
     最差的情况下空间复杂度为:O( n )      ;退化为冒泡排序的情况




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漫天飞舞的雪花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值