在c ++中使用合并排序算法实现Count反转

时间:2017-11-15 10:40:23

标签: c++ algorithm

我需要为家庭作业实现计数反转算法,但我无法弄清楚我的代码中存在什么问题。我们的教授要求我们用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.我希望有人可以指出我的错误在哪里。

1 个答案:

答案 0 :(得分:3)

您的基本想法是正确的,但代码中存在2个问题。一个是概念性的,另一个是代码。

  1. 在合并步骤的else块中,您将反转增加1。相反,您应该根据左侧部分的值增加它。所以在else块中你应该使用inversion += mid-i;代替inversion++;因为,你需要实际计算所需的掉期数量。此时,对于array[j]的值,您有mid - i(左数组的其余部分)实际需要交换的元素数量array[j]。这意味着,如果您要使用冒泡排序,则需要将左侧数组(mid-i)中的所有其余元素与此单个值(array[j])交换。因此,对于此array[j],您应该增加左子数组中剩余的元素数。

  2. count_inversion的递归调用中,您在每个调用中都缺少一些值。例如我们说n=5。然后,您在左侧使用5/2 = 2,在右侧使用5/2 = 2。但是你错过了右边的最后一个元素。您可以通过在第二次递归调用中使用以下内容来解决此问题。在这里,您应该使用您在第一次通话时使用的剩余长度。

    count_inversion(a + (n / 2), n - n / 2);

  3. 来自您的一些修改后的代码,包含修复程序:https://ideone.com/raKD7T