快速排序

一.挖坊填补法

先选择一个标准值,将它取出,我们把它看做一个坑。

我们选择最低的一位作为标准值。

从后向前遍历,(高指针向低指针遍历)找到比这个标准值小的值就放入坑中,这时就产生了一个新的坑。

再从前向后遍历,(低指针向高指针遍历)找到比标准值大的值则放入坑中,这时产生了一个新的坑。

再从后向前遍历(高指针向低指针遍历)。。。。。

当高低指针相遇的时候,将标准值放入。这时标准值得左边都是比标准值小的,标准值得后面都是比标准值大的。

将左边,和右边看成独立数组,重复以上步骤。(递归实现)

代码:

int  FindStandard(int *arr,int low,int high)
{
    int num = arr[low];
    while(low < high)
    {
        //从后向前找
        while(low < high)
        {
            if(arr[high] < num)
            {
                arr[low] = arr[high];
                break;
            }
            high--;
        }
        //从前向后找
        while(low < high)
        {
            if(arr[low] > num)
            {
                arr[high] = arr[low];
                break;    
            }
            low++;    
        }
    }
    arr[low] = num;
    return low;
}
void QuickSort(int* arr,int low, int high)
{
    if(arr == NULL || low >= high)
        return;
    int Standard = FindStandard(arr,low,high);
    //以标准值为界限分为左半部分和右半部分,再分别重复以上步骤
    QuickSort(arr,low,Standard-1);
    QuickSort(arr,Standard+1,high);
}

优化1:如何提高系统效率?while循环嵌套的效率比较低,改用for,从一个方向遍历。则有了第二种方法:区间分割法。

二. 区间分割法

思路:将最后一个数先作为标准值,然后从低位向高位遍历,比较。设置一个标记,为比标准值小的数。

如果此数比标准值小,看是否为标记的下一个,是则标记++;不是则与标记的下一个值交换。这样可以保证从最低位到标记都是比标准值小的。

最后将最后一位的值也就是标准值与标记的下一个交换。

这样标准值前面的都是比标准值小的,标准值后面的都是标准值大的。标准值位置即排好序的位置。

将标准值左右分为两个数组。左右分别调用此

代码:

int FindStandard(int* arr,int low,int high)
{
    int small = low-1;//标记位
    for(low;low < high;low++)
    {
        if(arr[low] < arr[high])
        {
            //如果该比标准值小的值不是标记的下一位,那么标记的下一位与该值交换。是则small++
            //所以可以先small++,如果不是标记的下一位则交换,是则不执行。
            if( ++small != low )
            {
                arr[small] = arr[small]^arr[low];
                arr[low] = arr[small]^arr[low];
                arr[small] = arr[small]^arr[low];
            }
        }
    }
    //如果标准值就是最后一位则不用交换
    if(++small != high)
    {
        arr[small] = arr[small]^arr[high];
        arr[high] = arr[small]^arr[high];
        arr[small] = arr[small]^arr[high];
    }
    return small;
}
void QuickSort(int*arr,int low,int high)
{
    if(arr == NULL || low >= high )
        return;
    int standard = FindStandard(arr,low,high);
    
    QuickSort(arr,low,standard-1);
    QuickSort(arr,standard+1,high);
}

优化2:如何避免标准值是最大值或最小值?     因为我们的思路是,找到一个标准值将它分为左右两个部分,如果标准是最大值,那么没有达到目的,并且邹静FindStandard的循环没有做事。  所以为了避免这种偶然事件发生我们可以选3个数,最低位,最高位和中间位。在他们3个中选择一个中间位,这样绝不可能是最大值或者最小值了。为什么不用随机数? 随机数的种子根据时间生成随机数,生成的3个数相同的概率比较大。

优化3:如何避免系统异常?  因为代码中用到了递归,系统自动调用,压入栈中,这是我们不能控制的,可能发生异常。

优化4:数据过少怎么办?   如果数据过少,我们就没有必要使用快排了,使用插入排序。

优化5:什么情况对快排来讲最坏?原因? 倒序的排号序的数组。因为

原文地址:https://www.cnblogs.com/Lune-Qiu/p/9104933.html