为什么这两个版本的quicksort在比较次数方面产生了巨大差异?

时间:2012-11-21 08:01:34

标签: c++ algorithm sorting quicksort

我在下面有两个不同的快速排序实现。我已经验证了这些版本的quicksort工作的意义,他们将对我正确给出的任何数组进行排序。如果您注意到(至少在我看来),当数组大小n大于8时,版本#2与版本#1完全相同。因此,当我同时提供这两个函数时,我希望一个大于8的相同大小的数组,它们应该平均进行相同数量的组件比较,但它们不会。

对于n > 8,这两个函数都使用sort3()partition()函数。我已经列出了以下内容,以向您展示我如何计算组件明智比较的数量。

我知道W(n),这些quicksort实现的理论最坏情况比较是(n(n + 2)/ 4)+8。因此,对于数组大小n = 500W(n) = 62758。对于大小为n = 500的数组的测试运行,版本#1平均进行大约5000次比较,这是合理的。但是,版本#2平均进行80000次比较。显然这不是正确的 - 版本#2正在进行比理论W(n)更多的比较,并且它与版本#1完全相同(至少在我看来)。

您是否在版本2中看到了错误?

版本#1:

void Quicksort_M3(int S[], int low, int hi)
{
    if(low < hi)
    {
        if((low+1) == hi)
        {
            comparisons++;
            if(S[low] > S[hi])
                swap(S[low],S[hi]);
        }
        else
        {
            Sort3(S,low,hi);
            if((low+2)<hi)
            {
                swap(S[low+1],S[(low+hi)/2]);
                int q = partition(S, low+1, hi-1);
                Quicksort_M3(S, low, q-1);
                Quicksort_M3(S, q+1, hi);
            }
        }
    }
}

版本#2:

void Quicksort_Insert_M3(int S[], int n, int low, int hi)
{
    if((hi-low)<=8)
        Insertionsort(S,n);
    else 
    {
        if(low < hi)
        {
            if((low+1) == hi)
            {
                comparisons++;
                if(S[low] > S[hi])
                    swap(S[low],S[hi]);
            }
            else
            {
                Sort3(S,low,hi);
                if((low+2)<hi)
                {
                    swap(S[low+1],S[(low+hi)/2]);
                    int q = partition(S, low+1, hi-1);
                    Quicksort_Insert_M3(S, n, low, q-1);
                    Quicksort_Insert_M3(S, n, q+1, hi);
                }
            }
        }
    }
}

分区:

int partition(int *S,int l, int u)
{
    int x = S[l];
    int j = l;
    for(int i=l+1; i<=u; i++)
    {
        comparisons++;
        if(S[i] < x)
        {   
            j++;
            swap(S[i],S[j]);
        }

    }
    int p = j;
    swap(S[l],S[p]);
    return p;
}

Sort3:

int Sort3(int list[], int p, int r)
{
    int median = (p + r) / 2;
    comparisons++;
    if(list[p] <= list[median])
    {
        comparisons++;
        if(list[median]>list[r])
        {
            comparisons++;
            if(list[p]<list[r])
            {
                int temp = list[p];
                list[p] = list[r];
                list[r] = list[median];
                list[median] = temp;
            }
            else
            {
                exchange(list,median,r);
            }
        }
        else
            ;

    }
    else
    {
        comparisons++;
        if(list[p] > list[r])
        {
            comparisons++;
            if(list[median] < list[r])
            {
                int temp = list[p];
                list[p] = list[median];
                list[median] = list[r];
                list[r] = temp;
            }
            else
            {
                exchange(list,p,r);
            }
        }
        else
        {
            exchange(list,p,median);
        }

    }


    return list[r];
}

1 个答案:

答案 0 :(得分:5)

我认为您的错误是当您执行插入排序时,您仍然使用数组的原始大小。因此,您最终会对整个数组执行插入排序。