我在下面有两个不同的快速排序实现。我已经验证了这些版本的quicksort工作的意义,他们将对我正确给出的任何数组进行排序。如果您注意到(至少在我看来),当数组大小n
大于8时,版本#2与版本#1完全相同。因此,当我同时提供这两个函数时,我希望一个大于8的相同大小的数组,它们应该平均进行相同数量的组件比较,但它们不会。
对于n > 8
,这两个函数都使用sort3()
和partition()
函数。我已经列出了以下内容,以向您展示我如何计算组件明智比较的数量。
我知道W(n)
,这些quicksort实现的理论最坏情况比较是(n(n + 2)/ 4)+8。因此,对于数组大小n = 500
,W(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];
}
答案 0 :(得分:5)
我认为您的错误是当您执行插入排序时,您仍然使用数组的原始大小。因此,您最终会对整个数组执行插入排序。