【问题标题】:merge sort is in infinite loop合并排序处于无限循环中
【发布时间】:2020-07-16 08:40:33
【问题描述】:

我正在尝试编写递归合并排序。 但是,当我运行代码时,我发现代码没有通过正确的数组。 请帮我解决问题。

void merge_sort_recursive(int *arr, int left, int right) {
    int mid;
    while (left < right) { 
        mid = (left + right) / 2;
        merge_sort_recursive(arr, left, mid);
        merge_sort_recursive(arr, mid + 1, right);
        merge_recursive(arr, left, mid, right);
    }
    for (int i = 0; i < 4; i++)
        cout << arr[i] << " ";
    cout << endl;
}

void merge_recursive(int *arr, int left, int mid, int right) {
    int *buffer = new int[right + 1]; 
    int lPtr = left; 
    int rPtr = mid + 1;
    int bPtr = left; 

    while (lPtr <= mid && rPtr <= right) {
        if (arr[lPtr] < arr[rPtr]) 
            buffer[bPtr++] = arr[lPtr++];
        else
            buffer[bPtr++] = arr[rPtr++];
    }

    if (lPtr > mid) 
        for (int i = rPtr; i <= right; i++)
            buffer[bPtr++] = arr[i];
    else 
        for (int i = lPtr; i <= mid; i++)
            buffer[bPtr++] = arr[i];

    for (int i = left; i <= right; i++) 
        arr[i] = buffer[i]; 
}

【问题讨论】:

  • while (left &lt; right)更改为if (left &lt; right),您的代码将完美运行。
  • 请注意,您正在泄漏内存。我看到 new[] 但没有匹配的 delete[]
  • 旁注:调试器非常擅长帮助理解无限循环。在调试器中运行程序。等待程序进入无限循环。循环几次,观察程序在做什么。特别注意与退出条件相关的变量。
  • @ReginaKang:您可以通过单击分数下方的灰色复选标记来接受其中一个答案。

标签: c++ algorithm sorting mergesort


【解决方案1】:

您的代码中存在多个问题:

  • 在函数merge_sort_recursive 中,您不应该循环while (left &lt; right),而是递归地继续if (left &lt; right)
  • 您应该删除merge_sort_recursive 中的输出。我想你只是为了调试目的而把它放在那里。
  • 在函数merge_recursive 中分配一个大小为right + 1 的临时数组。这太大了,right - left + 1 就足够了(对索引值进行了调整)。
  • 你没有delete临时数组,导致大量内存泄漏,
  • 第一个合并循环中的测试应使用&lt;= 而不是&lt;

主要问题是while 循环阻止从递归调用返回。

这是修改后的版本:

void merge_sort_recursive(int *arr, int left, int right) {
    if (left < right) { 
        int mid = (left + right) / 2;
        merge_sort_recursive(arr, left, mid);
        merge_sort_recursive(arr, mid + 1, right);
        merge_recursive(arr, left, mid, right);
    }
}

void merge_recursive(int *arr, int left, int mid, int right) {
    int *buffer = new int[right - left + 1];
    int lPtr = left;
    int rPtr = mid + 1;
    int bPtr = 0;

    while (lPtr <= mid && rPtr <= right) {
        if (arr[lPtr] <= arr[rPtr]) 
            buffer[bPtr++] = arr[lPtr++];
        else
            buffer[bPtr++] = arr[rPtr++];
    }
    /* copy the remaining elements from the left part */
    while (lPtr <= mid) {
        buffer[bPtr++] = arr[lPtr++];
    }
    /* no need to copy the remaining elements from the right part 
       because they already are at the final position */
    for (int i = 0; i < bPtr; i++) {
        arr[left + i] = buffer[i];
    }
    delete[] buffer;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-15
    • 2018-05-02
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多