我正在尝试跟踪此递归调用,但我假设它确定数组是否按升序排序是不正确的。关于我如何做到这一点的任何建议?
bool g(int a[], int l, int r) {
if(l==r)
return true;
if((r-l)==1)
return (a[l] > a[r]);
else {
int m = (l+r)/2;
return (a,l,m) && (a[m] > a[m+1]) && g(a,m+1,r);
}
}
答案 0 :(得分:2)
最后一行应该是:
return g(a,l,m) && (a[m] > a[m+1]) && g(a,m+1,r);
如果您只是写(a,l,m)
C ++将其视为逗号运算符,其结果只是您的情况中的最后一个参数(m
,这大部分是“真实的”并且阻止其他任何操作求值)。
答案 1 :(得分:0)
引导您完成如何分析:
g()
适用于一组ints l
和r
用于索引数组l
== r
是终止条件...始终返回true
r - l == 1
暗示r
预计会超过l
,将对它们的理解强化为左(较低索引)和范围右端在数组中:如果l
和r
是并排的,那么a[l] > a[r]
会检查降序顺序m = (l + r) / 2
- 这是找到左右两端之间的中间点,但至关重要如果l + r
是奇数它向下舍入,所以我们最好考虑这个理解算法时的“边缘情况”g(a,l,m)
......这意味着在l..m
&& a(m) > a[m+1] &&
测试降序顺序g(a, m+1, r)
对范围m+1..r
所以...当r-l> 1有2个或更多要素被考虑。如果我们从最小的差距开始,而不是特殊的(2),并通过更大的差距,直到我们已经建立了依赖于已证实的工作较小差距的明确趋势:
g(a,l,l+1)
(测试[l]> a [l + 1])&& a[l+1] > a[l+2] && g(a,l+2,l+2)
(后者始终为真),所以两个重要测试是a[l] > a[l+1] > a[l+2]
(使用数学语义)g(a,l+2,l+3)
,它将测试a[l+2] > a[l+3]
,因此它正在努力确保它们全部按顺序排列g(a, l, l+2)
(我们自己证明了自己在上面工作)&& a[l+2] > a[l+3] && g(a,l+3,l+4)
(最后,r-l == 1
我们上面也观察过)... 显然,当rl == 5 g()
递归测试2和3的rl间隙(上面证实)时,6个测试3和3,7 4和3等...所以我们可以看到是否适用于任何大小差距。