我已经为快速排序提供了这个预定义的代码,不需要做太多改动:
我知道我们已经对此有疑问,但这是不同的,因为这里预定了逻辑。
void quicksort(int a[], int l, int r)
{
if (r <= l) return;
/* call for partition function that you modify */
quicksort(a, l, i-1);
quicksort(a, i+1, r);
}
int partition(int a[], int l, int r)
{ int i = l-1, j = r; int v = a[r];
for (;;)
{
while (a[++i] < v) ;
while (v < a[--j]) if (j == l) break;
if (i >= j) break;
exch(a[i], a[j]);
}
exch(a[i], a[r]);
return i;
}
我们只需要稍作修改,以便快速排序返回它的比较次数,并且分区函数(总计)在排序给定数组a时执行了。 **在这些比较中,只计算涉及数组元素的比较。在计算这些比较时,不允许使用任何全局变量。 **
我已按照以下方式实施,如果我在某个地方弄错了,请告诉我:
int partition(int a[], int l, int r, int& count) {
int i = l - 1, j = r; int v = a[r];
for (;;) {
while (a[++i] < v) count++;
while (v < a[--j]) {
count++;
if (j == l) break;
}
if (i >= j) break;
swap(a[i], a[j]);
}
swap(a[i], a[r]);
return i;
}
int quickSort(int a[], int l, int r) {
int count = 0;
if (r <= l) return 0;
int i = partition(a, l, r, count);
return count + quickSort(a, l, i - 1) + quickSort(a, i + 1, r);
}
一旦你确认,我将与你分享我对此研究的惊人结果。
答案 0 :(得分:0)
ricis评论作为解决方案很好。有一种可能采用的替代方法可以推广到std :: sort和其他算法,那就是进行计数比较。
的内容
struct CountingComparer{
CountingComparer():count(0){}
CountingComparer(const CountingComparer& cc):count(cc.count){}
bool operator()(int lhs, int rhs){
count;
return lhs < rhs;
}
size_t count;
};
现在您需要更改函数的签名以将比较器添加为最后一个参数。喜欢
template<typename COMP>
void quicksort( .... , COMP comp){
和分区功能一样的改变。然后通过
进行比较 while (comp(a[++i],v)) and
while (comp(v, a[--j])) respectively.
您需要确保在模板参数中有对比较器的引用。
CountingComparer comp;
quicksort(... , std::ref(comp));
确保不复制comp。
排序后,您可以在comp.count中找到比较次数。
维基百科页面上广泛讨论了您的快速排序行为。预计排序的数组表现不佳,而随机元素表现良好。
for (;;)
{
while (a[++i] < v) ;
while (v < a[--j]) if (j == l) break;
if (i >= j) break;
exch(a[i], a[j]);
}
exch(a[i], a[r]);
while (a[++i] < v);
语句利用了枢轴`v或a [r]&#39;元素是最右边的元素。所以枢轴元件就像一个守卫。 while (v < a[--j]) if (j == l) break;
没有透视的保证。而是检查最左边的限制。 swap(a[i], a[r]);
,将枢轴元素排列到正确的位置。