C语言:为什么我的代码会陷入无限循环,以及如何使用递归解决合并排序问题?

时间:2019-02-11 05:32:52

标签: c algorithm sorting

我在这段代码中遇到两个问题。

第一个问题是无限循环,发生于77〜79。当我更改测试数据并使用merge方法时,将出现无限循环,R1将更改为4198739.但是如果我使用mergeSort方法,则不会出现预期的问题。如下图所示:

  int M = 2;
  int R1 = 4;
  int arr[] = {3,9,8,20};
  merge(arr, L, M, R1);

第二个问题发生在57到69行之间。在这个mergeSort方法中,我试图将无序数组划分为子数组。但是,对原始数组没有任何影响。

这是我的代码。 Merge Sort in C

void mergeSort(int arr[], int L, int R)
{
  if(L<R) { 
    return ;
  } else {
    int M = (L+R) / 2;
    mergeSort(arr, L, M);
    mergeSort(arr, M+1, R);
    merge(arr, L, M+1 ,R);
  }
}

4 个答案:

答案 0 :(得分:0)

代码的逻辑中有几个错误。我将解决正确的代码。 首先是几个指针。

  1. 逻辑处理数组索引,不要与数组限制混淆。
  2. 我已经使用sizeof运算符来获取数组的上限。
  3. 尽可能使用if-else。

完整的代码无法在此处正确添加,因此-https://pastebin.com/ixickcQA

主要错误在这里:

for(i=M;i<=R;i++)               //1. <= as R is also an index
{
     right[i-M] = arr[i];
}

答案 1 :(得分:0)

这是(其他)答案所链接的代码:

#include <stdio.h>

    void merge(int arr[], int L, int M, int R) 
    {
        int LEFT_SIZE = M-L;
        int RIGHT_SIZE = R-M+1;
        int left[LEFT_SIZE];
        int right[RIGHT_SIZE];
        int i,j,k;

        for(i=L;i<M;i++)
        {
            left[i-L] = arr[i];
        }
        for(i=M;i<=R;i++)               //1. <= as R is also an index
        {
            right[i-M] = arr[i];
        }

        i=0;
        j=0;
        k=L;

        while(i<LEFT_SIZE && j<RIGHT_SIZE)
        {
            if(left[i] <= right[j])         //2. <= so that duplicates are not ignored
            {
                arr[k] = left[i];
                i++;
            } 
            else                    //3. use else to keep up the computing speed
            {
                arr[k] = right[j];
                j++;
            }
            k++;
        }

        while(i<LEFT_SIZE)
        {
            arr[k] = left[i];
            i++;
            k++;
        }

        while(j<RIGHT_SIZE)
        {
            arr[k] = right[j];
            j++;
            k++;
        }

    }

    void mergeSort(int arr[], int L, int R)
    {
        if(L<R)                     //4. Better
        {
            int M = (L+R) / 2;
            mergeSort(arr, L, M);
            mergeSort(arr, M+1, R);
            merge(arr, L, M+1 ,R);
        }
    }

    int main() {

        int arr[] = {3,9,20,8,21,22};

        mergeSort(arr, 0, (sizeof(arr)/sizeof(int))-1); //5. Use size-1 as we are dealing with indices

        int i;
        printf("Final\n");
        for(i=0; i<(sizeof(arr)/sizeof(int)); i++) 
        {
            printf("i=%d, R=%d,arr[i]=%d\n",i,(sizeof(arr)/sizeof(int)), arr[i]);
        }
    }

因此将代码插入答案中没问题

答案 2 :(得分:0)

mergeSort中替换为:

if(L<R)

通过这个:

if(L>=R)

如果存在L<R,则它将始终被满足,因为索引L将始终小于R(在开始时)。这就是导致无限循环的原因。

答案 3 :(得分:0)

您的代码在if语句中包含逻辑错误。试试这个:

void mergesort(int a[], int l, int r) {
  int m;
  if (l < r) {
    // same as (l+r) / 2 but for avoiding overflow
    m = l + (r - l) / 2;

    // recur both parts
    mergesort(a, l, m);
    mergesort(a, m + 1, r);
    merge(a, l, m, r); // merging parts
  }
}