快排算法

include

include

using namespace std;

/*
时间复杂度:
递归时间复杂度公式: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(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况
最差的情况下空间复杂度为:O( n ) ;退化为冒泡排序的情况

*/


//快排:不稳定,平均时间复杂度为O(NlogN),空间复杂度为O(1),就地排序! 
void quick_sort(vector<int>&array,int low,int high) //左 右都是闭的

{
    //终止条件,只剩一个数low==high
    //执行条件:low<high 
    if (low<high)
    {
        //分割数组,设置pivot,找出pivot的index,并把比pivot大的放到index右边 
        int pivot = array[low];
        int i = low,j = high;
        while(i<j)
        {
            //右->左:找到第一个小于pivot的数
            while(array[j]>=pivot && j>i) //擦,这里要&&上j>i防止j无限减小超出数组范围而溢出 
                j--;
            if(i<j)
            {
                array[i] = array[j];
                i++; //把i的坑填上,i的位置不再需要改变了 
            }
            while(array[i]<=pivot && i<j) //同理!! 
                i++;
            if(i<j)
            {
                array[j] = array[i];
                j--; //把j的坑填上,j-- 
            } 
        } 
        //跳出循环说明找到了i=j的index
        array[i] = pivot; //把pivot放到正确的位置上
        int pivotIndex = i;
        //递归 
        quick_sort(array,low,pivotIndex-1);
        quick_sort(array,pivotIndex+1,high);
    }
}
/*  这是子函数模式 
int partition(vector<int>&array,int low,int high)
{
    //选择第一个数作为pivot基准,比pivot小的都移到左边,
    //比pivot大的都移到右边,最后返回pivot所处的Index;
    //
    int pivot = array[low];
    int i = low,j = high;
    while(i<j)
    {
        //右->左:找到第一个小于pivot的数
        while(array[j]>=pivot && j>i) //擦,这里要&&上j>i防止j无限减小超出数组范围而溢出 
            j--;
        if(i<j)
            {
                array[i] = array[j];
                i++; //把i的坑填上,i的位置不再需要改变了 
            }
        while(array[i]<=pivot && i<j) //同理!! 
            i++;
        if(i<j)
        {
            array[j] = array[i];
            j--; //把j的坑填上,j-- 
        } 
    } 
    //跳出循环说明找到了i=j的index
    array[i] = pivot; //把pivot放到正确的位置上
    return i; 
}


void quick_sort(vector<int>&array,int low,int high) //左 右都是闭的
{
    //终止条件,只剩一个数low==high
    //执行条件:low<high 
    if (low<high)
    {
        int pivotIndex = partition(array,low,high); //函数里对array向量的元素进行了移动,需要传引用保存 
        quick_sort(array,low,pivotIndex-1);
        quick_sort(array,pivotIndex+1,high);
    }
}
*/ 

int main(int argc, char** argv) {
    vector<int> array;
    for(int i=0;i<10;i++)
    { 
        array.push_back(5-i);
        cout<<array[i]<<',';
    }
    cout<<endl;  
    quick_sort(array,0,9);
    for(int i=0;i<10;i++)
        cout<<array[i]<<',';
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值