【问题标题】:C implementation of merge sort, as shown in Cormen's et al "Introduction to algortithms" not working properly合并排序的 C 实现,如 Cormen 等人的“算法简介”中所示,无法正常工作
【发布时间】:2018-04-19 07:23:30
【问题描述】:

我正在尝试使用 C 来实现这个合并排序伪代码

我想出了这个

int p = 0, r = SEIZE-1, i, j, k;
int q = (p + r)/2;
int n1 = q-p+1, n2 = r-q;
float A[SEIZE] = { 125.6, 67.2, 3.21, 422, 54, 87 }, L[n1], R[n2];

printf("{ ");
for( k = 0 ; k < SEIZE ; k++ ){
    printf("%.1f ", A[k]);
}
printf(" }\n");

for( i = 0 ; i < n1 ; i++ ){
    L[i] = A[p+i];
}
for( j = 0 ; j < n2 ; j++ ){
    R[j] = A[q+j+1];
}
L[n1] = '\0';
R[n2] = '\0';

i = 0;
j = 0;

for( k = p ; k <= r; k++ ){
    if( L[i] <= R[j] ){
        A[k] = L[i];
        i = i+1;
    }
    else{
        A[k] = R[j];
        j = j+1;
    }
}

printf("{ ");
for( k = 0 ; k < SEIZE ; k++ ){
    printf("%.1f ", A[k]);
}
printf(" }\n");

但是,这发生在

第一组数字是未排序的,第二组应该是 排序的,但如您所见,算法没有对其进行排序;我认为问题源于错误地尝试将书中的 base-1 数组转换为 C 的 base-0,但我不太确定。你能帮我找出问题吗?

提前致谢。

【问题讨论】:

  • 能贴出完整的代码吗?

标签: c algorithm sorting merge mergesort


【解决方案1】:
  • 您混淆了 1 索引和 0 索引。您应该遵循算法所说的(1-indexing),或者您可以编写自己的 0-indexing 版本。

  • 还要查看错误的大小。我认为,您没有将两个排序数组传递给合并函数。如果您仔细考虑,merge 只不过是将已排序的数组按顺序排列在一起。我想您应该检查该数组是否已排序。

  • 不应将无穷大替换为 \0。这不合逻辑。您可以使用INT_MAX 或类似的东西来做到这一点。

  • 首先检查程序部分。首先检查排序功能是否正常工作。如果可行,则进行合并。这样您就可以轻松找到问题所在。

示例代码:

int merge(int *arr, int left, int middle, int right)
{
  int len1 = middle - left + 1;
  int len2 = right - middle;

  int arr1[len1];
  int arr2[len2];

  int i;
  for (i=0; i<len1; ++i)
    arr1[i] = arr[left + i];

  for (i=0; i<len2; ++i)
    arr2[i] = arr[middle + 1 + i];

  arr1[len1] = INT_MAX;
  arr2[len2] = INT_MAX;

  int j,k;
  j = 0;
  i = 0;

  for (k=left; k<=right; ++k)
    arr[k] = (arr1[i] <= arr2[j])? arr1[i++]:arr2[j++];

  return 0;
}

【讨论】:

    【解决方案2】:

    不要把L[n1]='\0'R[n2]='\0' 而是使用此逻辑进行合并

    i=0
    j=0
    k=p
    while(i<n1&&j<n2)
    {
        if(L[i]<=R[j])
        {
            arr[k]=L[i];
            i++;
        }
        else
        {
            arr[k]=R[j];
            j++;
        }
        k++;
    }
    //This following code for copying      remaining elements
    while(i<n1)
    {
        arr[k]=L[i];
        i++;
        k++;
    }
    while(j<n2)
    {
        arr[k]=R[j];
        j++;
        k++;
    }
    

    【讨论】:

      【解决方案3】:

      您的代码存在一些问题,但到目前为止,最大的问题是您认为您的算法应该对数组进行排序。不是。

      “合并”功能只是合并排序的一部分;它的功能是获取两个已经排序的子数组 - A[p..q-1] 和 A [q..r],我想,如果我正确地解释了你的伪代码——并将它们合并到一个已经排序的子数组中——A em>[p..r].

      所以要测试你对该函数的实现,你需要给它一个数组,它的两部分已经排序。

      要获得完全排序的数组,您需要完成合并排序的实现。 (您的书可能会在您尚未阅读的页面上为您提供算法的其余部分,或者将其设置为练习。)

      【讨论】:

      • 是的。我不知道 OP 如何如此确定这就是问题所在......无论如何这打破了MCVE(我的意思是问题)。我会紫外线,因为它是正确的。
      猜你喜欢
      • 2015-09-23
      • 2012-08-16
      • 2023-03-22
      • 2013-09-17
      • 1970-01-01
      • 2020-12-07
      • 1970-01-01
      • 2018-04-13
      • 2014-05-20
      相关资源
      最近更新 更多