我需要为家庭作业实现计数反转算法,但我无法弄清楚我的代码中存在什么问题。我们的教授要求我们用c ++实现计数反转(我没有工作)有很多)没有使用任何C ++库我只能包括<iostream>
并仅使用std作为输出(cout<<
),那就是它,他也给了我们这篇文章:
void count_inversion(int a[],int n){
count_inversion(a, n / 2);
count_inversion(a + (n / 2), n / 2);
count_inversion_merge(a, n / 2, n);
}
并说我们应该实现count_inversion_merge
函数并将此作为提示使用。
所以我试着调整一下代码,但仍然没有运气。
这是我的代码:
int count_inversion_merge(int array[], int mid, int n) {
for (k = 0; k < n; k++) {
if (j == n || (i < mid && array[i] < array[j])) {
b[k] = array[i];
i++;
} else {
b[k] = array[j];
j++;
inversion++;
}
}
}
我的第一个输入int a[] ={ 2, 4, 1, 3, 5 };
应该返回3,但它返回5
我的第二个输出应该是5,我得到5.我希望有人可以指出我的错误在哪里。
答案 0 :(得分:3)
您的基本想法是正确的,但代码中存在2个问题。一个是概念性的,另一个是代码。
在合并步骤的else块中,您将反转增加1。相反,您应该根据左侧部分的值增加它。所以在else块中你应该使用inversion += mid-i;
代替inversion++;
因为,你需要实际计算所需的掉期数量。此时,对于array[j]
的值,您有mid - i
(左数组的其余部分)实际需要交换的元素数量array[j]
。这意味着,如果您要使用冒泡排序,则需要将左侧数组(mid-i
)中的所有其余元素与此单个值(array[j]
)交换。因此,对于此array[j]
,您应该增加左子数组中剩余的元素数。
在count_inversion
的递归调用中,您在每个调用中都缺少一些值。例如我们说n=5
。然后,您在左侧使用5/2 = 2
,在右侧使用5/2 = 2
。但是你错过了右边的最后一个元素。您可以通过在第二次递归调用中使用以下内容来解决此问题。在这里,您应该使用您在第一次通话时使用的剩余长度。
count_inversion(a + (n / 2), n - n / 2);
来自您的一些修改后的代码,包含修复程序:https://ideone.com/raKD7T