【发布时间】:2016-07-22 21:02:34
【问题描述】:
我知道 Stack 中有很多这样的实现,但是我遇到了一个我无法处理的问题。
首先我在 khanacademy 使用 javascript 实现了合并排序,然后我将代码重写为 C++,并尝试计算数组中的反转数。
我尽我所能,并花了一个小时试图了解我做错了什么。我确实在堆栈中搜索了另一个实现并尝试更正我的代码。不幸的是,我不知道我做错了什么。我认为我计算了每次反转。在此先感谢您在了解问题所在方面提供的帮助。
我的代码:
int lowhalflength(int p, int q)
{
return q - p + 1;
}
int highhalflength(int q, int r)
{
return r - q;
}
int merge(int array[], int p, int q, int r, int lowhalf[], int highhalf[])
{
int k = p;
int i;
int j;
int count = 0;
for (int i = 0; k <= q; i++ , k++)
{
lowhalf[i] = array[k];
}
for (int i = 0; k <= r; i++ , k++)
{
highhalf[i] = array[k];
}
k = p;
i = 0;
j = 0;
while (i <= (q - p) && j <= r - (q + 1))
{
if (lowhalf[i] <= highhalf[j])
{
array[k] = lowhalf[i];
i++;
}
else
{
array[k] = highhalf[j];
j++;
count += q - 1;
}
k++;
}
while (i < lowhalflength(p, q))
{
array[k] = lowhalf[i];
k++;
i++;
}
while (j < highhalflength(q, r))
{
array[k] = highhalf[j];
k++;
j++;
}
return count;
}
mergeSort 函数:
int mergeSort(int array[], int p, int r)
{
int q = ((p + r) / 2);
int* lowhalf = new int[lowhalflength(p, q)];
int* highhalf = new int[highhalflength(q, r)];
int count = 0;
if (p < r)
{
q = ((p + r) / 2);
count = mergeSort(array, p, q);
count += mergeSort(array, q + 1, r);
count += merge(array, p, q, r, lowhalf, highhalf);
}
delete[] lowhalf;
delete[] highhalf;
return count;
}
对于数组 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1],输出是 46,而应该是 45。
编辑:
答案是把下面这行q-1改成q+j-k.我自己找的但是不知道怎么解释。任何提示或证明为什么它是正确的都是非常可取的。
【问题讨论】:
-
可能是学习如何使用调试器单步调试代码并观察每一步后变量值变化的良好起点。
-
你最初在哪里调用mergeSort?
-
@o_weisman 我像这样使用mergeSort。如果我在数组中有 10 个元素,我会调用 cout
-
你的算法和我的有点不同,但
count += q - 1不应该更像count = (q - p) - i吗?假设我正确理解了您的索引(可以肯定的是,这方面的机会很小)。 ?仅供参考,我常用的算法将所有中等范围的计算都隐藏起来,以支持指针数学。 something like this。从根本上讲,累积值是每当您从围栏的右侧移动某物时,从中点到下方攀爬左侧索引的距离就是该累积值。 -
@WhozCraig 不幸的是它没有给出正确的输出。;(
标签: c++ recursion mergesort divide-and-conquer