【问题标题】:Why does this merge sort algorithm not work properly?为什么这个归并排序算法不能正常工作?
【发布时间】:2021-07-11 15:03:01
【问题描述】:

我没有收到任何错误或警告。这是我的代码:

#include <iostream>

void merge(int arr[], int l, int m, int r);
void mergeSort(int arr[], int l, int r);

int main(){
    int arr[11] = {1, 9, 2, 5, 3, 10, 4, 8, 6, 7};

    mergeSort(arr, 0, 10);

    for(int i = 0; i < 11; i++){
        std::cout << arr[i] << "\t";
    }
    return 0;
}

void merge(int arr[], int l, int m, int r){
    int i = l;      // starting point of left subarray
    int j = m + 1;  // starting point of right subarray
    int k = l;      // starting point of temporary array
    int temp[11];
    while(i <= m && j <= r){
        if(arr[i] <= arr[j]){
            temp[k] = arr[i];
            i++;
        } else {
            temp[k] = arr[j];
            j++;
        }
        k++;
    }
    while(i <= m){
        temp[k] = arr[i];
        k++; i++;
    }
    while(j <= r){
        temp[k] = arr[j];
        k++; j++;
    }
    for(int s = l; s < 11; s++){
        arr[s] = temp[s];
    }
}

void mergeSort(int arr[], int l, int r){
    if(l < r) {
        int m = (l + r) / 2; // middle
        mergeSort(arr, l, m); // left subarray
        mergeSort(arr, m + 1, r); // right subarray
        merge(arr, l, m, r);
    }
}

这是我编译运行时得到的:

0 1 2 3 4 9 4199851 7208472 7667712 7669136 1996860265

左边部分好像已经排序了——虽然原来数组里没有0,然后一切都乱了套,右边部分全是废话。

如果有人可以帮助我,我将不胜感激 - 谢谢。

【问题讨论】:

  • merge 仅在lr 之间填充temp 的元素,但将arr 中的所有元素从l 复制到末尾。因此它会用一堆未初始化的垃圾覆盖arr
  • 原始数组中也有0。您声明它有 11 个元素,但只提供了 10 个初始化程序。然后将最后一个元素初始化为零。
  • @IgorTandetnik 但是 l 到 r 不包含整个数组吗? 'r' 实际上不是结尾吗?
  • 问题出在合并功能上。请通过l 循环到r 而不是11

标签: c++ mergesort


【解决方案1】:

问题在于合并功能。您必须循环通过lrinclusive 而不是11。请参阅参考代码以获得更好的理解。

参考代码

#include <iostream>

void merge(int arr[], int l, int m, int r);
void mergeSort(int arr[], int l, int r);

int main(){
    int arr[11] = {1, 9, 2, 5, 3, 10, 4, 8, 6, 7};

    mergeSort(arr, 0, 10);

    for(int i = 0; i < 11; i++){
        std::cout << arr[i] << "\t";
    }
    return 0;
}

void merge(int arr[], int l, int m, int r){
    int i = l;      // starting point of left subarray
    int j = m + 1;  // starting point of right subarray
    int k = l;      // starting point of temporary array
    int temp[11];
    while(i <= m && j <= r){
        if(arr[i] <= arr[j]){
            temp[k] = arr[i];
            i++;
        } else {
            temp[k] = arr[j];
            j++;
        }
        k++;
    }
    while(i <= m){
        temp[k] = arr[i];
        k++; i++;
    }
    while(j <= r){
        temp[k] = arr[j];
        k++; j++;
    }
    for(int s = l; s <= r; s++){
        arr[s] = temp[s];
    }
}

void mergeSort(int arr[], int l, int r){
    if(l < r) {
        int m = (l + r) / 2; // middle
        mergeSort(arr, l, m); // left subarray
        mergeSort(arr, m + 1, r); // right subarray
        merge(arr, l, m, r);
    }
}

输出

0 1 2 3 4 5 6 7 8 9 10

【讨论】:

  • 是的,这已经奏效了 - 非常感谢 Badhan Sen!
  • 欢迎您,@Wacy。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-19
  • 1970-01-01
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多