第四十二篇: 快速排序为什么快?

好家伙,

前端知识的学习要暂时告一段落了,要去准备某个小小的比赛了,复习一下以前的知识.

"快速排序为什么快?",这是上次一个学长对我的灵魂拷问,我忘了,准确的说也没完全搞懂.

所以,今天来搞搞它.

 

上一个c语言朴实无华的快速排序: (功能:输入四个数,排序,从小到大输出)

#include<stdio.h>
int a[5];

void quicksort(int left,int right) //快速排序
{
    int i,j,t,temp; //i为左指针,j为右指针,temp为基准数
    if(left>right) 
        return;
    temp=a[left];   
    i=left;
    j=right;
    while(i!=j)
    {    
        while(a[j]>=temp && i<j)//从右向左找比基准数大的数
            j--;
        while(a[i]<=temp && i<j)//从左向右找比基准数大的数
            i++;
    
        if(i<j)    //若i,j不相遇,交换两数在数组中的位置
        {
        t=a[i];    
        a[i]=a[j];
        a[j]=t;
        }
    }
    
    a[left]=a[i];    //归位基准数
    a[i]=temp;    

    quicksort(left,i-1);  //基准数左边,递归
    quicksort(i+1,right);    //基准数右边,递归
    return;
}

int main()
{
    int i,j;
    
    printf("请输入四个数:"); //输入
    for(i=1;i<=4;i++)
        scanf("%d",&a[i]);

    quicksort(1,4);  //调用快速排序

    for(i=1;i<=4;i++)    //遍历输出
        printf("%d ",a[i]);
    getchar();
    return 0;

}

 

对于不同排序算法之间的衡量方式就是通过程序执行所占用的时间空间两个维度去考量。.

 

先解释一下时间复杂度

 

1.时间复杂度

若存在函数 f(n),使得当 n 趋近于无穷大时,T(n)/ f(n))的极限值为不等于零的常数,则称 f(n)是 T(n)的同数量级函数。

记作 T(n)= O(f(n)),称 O(f(n))为算法的渐进时间复杂度,简称时间复杂度。

简单理解就是一个算法或是一个程序在运行时,所消耗的时间(或者代码被执行的总次数)。

 

 2.

递归算法的时间复杂度公式:T[n] = aT[n/b] + f(n)  ;(至于怎么来的下次写)

 

以下是推导: (推导原文来自:https://blog.csdn.net/qfikh/article/details/52870875)

 

在最优的情况(即每次都取到中间数)下快速排序时间复杂度的计算(用迭代法):
                                          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;(m感觉可以理解为递归树的层数)

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

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

               n比上nlogn,n不要了

               综上所述:

    <1>快速排序最优的情况下时间复杂度为:O( nlogn ), ( 秒啊 )

    <2>快速排序的平均时间复杂度也是:O(nlogn)  (不知道怎么来的,要去问问学长)

      <3>还有最差情况(每次都取到最大值), 那么该情况下的时间复杂度就是O( n*n )

 

3.总的来说就是快排的时间复杂度低了,[干碎冒泡的平均O( n*n )],所以他快.

 

结束.

posted @ 2021-11-25 01:42  养肥胖虎  阅读(73)  评论(0编辑  收藏  举报