巧解快速排序时间复杂度

快速排序时间复杂度

递归算法的时间复杂度=递归次数*每次递归遍历的次数

我们来看一下快速排序算法的时间复杂度需要怎么来算呢?
代码实现:

//左右指针法  不断缩放  
//思路 begin 找大的  end 找小的  
//还要注意  如果是选endkeybegin先走 否则end先走  
//当选择end时候  因为当最后一次 endbegin差一个距离时候 如果先走end那会导致  
//把实际较小的没有交换 因为换之前 大小是左边小右边大 如果end先走 等于把begin所在的较小的换到最后去  
int PartSort1(int* a, int begin, int end)  
{  
    int& key = a[end];  
    while (begin < end)  
    {  

        //begin找大  
        while (begin < end&&a[begin] <= key)//这里注意的是<=  小心有重复数字  
            begin++;  
        //end找小  
        while (begin < end&&a[end] >= key)  
            end--;  
        if(begin<end)  
            swap(a[begin], a[end]);  
    }  

    //最好出来begin位置 一定是大于key的  
    swap(a[begin], key);  
    return begin;  
}  

void QuickSort(int* a, int begin,int end)  
{  
    if (begin >= end)  
        return;  
    else  
    {  
        int div = PartSort1(a, begin, end);  
        QuickSort(a, begin, div - 1);  
        QuickSort(a, div+1, end);  
    }  
}  

快速排序我们可以近似的想成一个完全二叉树
这里写图片描述

一个数组的容量是N,第一层递归遍历的次数是N,因为数组里每个数字都需要和key比较,那么接下来遍历分出来的两个区间,总的遍历次数还会是近似是N,以此类推,直到分为最后一个,也就是说树的高度是lgn,也就是递归次数,所以时间复杂度是N*lgN.

进阶:

问题:
有100万个数字,找出第10万个大的,这个问题,首先不是大数据问题,内存是可以放下的,这是快速排序的变形问题,第10万个大的其实是让我们找div=10万,(快速排序返回的div,其实就是下标,也就是数字在数组的准确序号[序号指的是第几个大])下面给出实现代码

int PartSort1(int* a, int begin, int end)  
{  
    int& key = a[end];  
    while (begin < end)  
    {  

        //begin找大  
        while (begin < end&&a[begin] <= key)//这里注意的是<=  小心有重复数字  
            begin++;  
        //end找小  
        while (begin < end&&a[end] >= key)  
            end--;  
        if(begin<end)  
            swap(a[begin], a[end]);  
    }  

    //最好出来begin位置 一定是大于key的  
    swap(a[begin], key);  
    return begin;  
}  

void QuickSort(int* a, int begin,int end)  
{  
    if (begin >= end)  
        return;  
    else  
    {  
        int div = PartSort1(a, begin, end);  
        if(div==100000)
        return a[div]
        else if(div>100000)
        QuickSort(a, begin, div - 1);  
        else
        QuickSort(a, div+1, end);  
    }  
}  

那这个代码的时间复杂度是多少呢?
这里写图片描述
我们可以用数形结合的方法,这个算法相当于一直走的是树的左枝,其余的都没有走,这其实就相当于变成了单链表,那遍历单链表的时间复杂度其实就是O(n),同理这个代码的时间复杂度也是O(n),

通过这个题我们可以看出数形结合有时候非常的清晰直观

猜你喜欢

转载自blog.csdn.net/qq_25424545/article/details/80068682