c++ 为什么我得到一个不正确的o/p(0 4 0 0 0 0 0)为下面的合并排序程序?[关闭]

zzzyeukh  于 2023-07-01  发布在  其他
关注(0)|答案(2)|浏览(112)

**关闭。**此题需要debugging details。目前不接受答复。

编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答这个问题。
4天前关闭。
Improve this question
我已经写了一个合并排序的程序,并在程序本身中传递值。生成的输出大多为零。是因为while循环中的一些错误,还是因为我的递归逻辑不正确?

void merge(int arr[], int s, int e)
{

    int mid = s + (e - s) / 2;

    // the length of the two arrays that we are going to divide the main array in

    int m = mid - s + 1;
    int n = e - mid;

    int* arr1 = new int[m];
    int* arr2 = new int[n];

    //copying values to arr1 and arr2 from the main array arr
    int x = s;
    for (int i = 0; i < m; i++) {
        arr1[i] = arr[x + i];
    }
    for (int j = mid + 1; j < n; j++) {
        arr2[j] = arr[mid + 1 + j];
    }

    int i = 0; // for arr1
    int j = 0; // for arr2
    int k = s; // because this is for the main array

    while (i < m && j < n) {
        if (arr1[i] <= arr2[j]) {
            arr[k] = arr1[i];
            i++;
            k++;
        }

        else {
            arr[k] = arr2[j];
            k++;
            j++;
        }

        while (i < m) {
            arr[k] = arr1[i];
            k++;
            i++;
        }

        while (j < n) {
            arr[k] = arr2[j];
            k++;
            j++;
        }
    }

    delete[] arr1;
    delete[] arr2;
}

//the recursive function
void divide(int arr[], int s, int e)
{

    if (s >= e)
        return;
    int mid = s + (e - s) / 2;
    divide(arr, s, mid);
    divide(arr, mid + 1, e);
    merge(arr, s, e);
}

#include <iostream>
using namespace std;

int main()
{

    int n = 8;
    int arr[8] = { 4, 8, 9, 7, 6, 2, 3, 1 };

    divide(arr, 0, n - 1);

    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }

    return 0;
}

我得到的上述代码的输出是-> 0 4 0 0 0 0 0 0

esbemjvw

esbemjvw1#

你对你的变量感到非常困惑。

int m = mid - s + 1;
int n = e - mid;

int* arr1 = new int[m];
int* arr2 = new int[n];

int x = s;
for (int i = 0; i < m; i++) {
    arr1[i] = arr[x + i];
}
for (int j = mid + 1; j < n; j++) {
    arr2[j] = arr[mid + 1 + j];
}

m是中点,是整个数组的索引。如果是不是数组第一部分的元素个数。只有当s等于零时,这才是真的。
所以这是不正确的

int* arr1 = new int[m];

应该是

int* arr1 = new int[m - s];

而这个循环是不正确的

int x = s;
for (int i = 0; i < m; i++) {
    arr1[i] = arr[x + i];
}

应该是的

for (int i = s; i < m; i++) {
    arr1[i - s] = arr[i];
}

我没有指出所有的错误,但你明白了。想想你的变量意味着什么,这样你才能正确地使用它们。添加一些注解来解释它们的意思也不会有什么坏处,这样你或其他任何人就不会感到困惑。

m4pnthwp

m4pnthwp2#

这个for循环

for (int j = mid + 1; j < n; j++) {
    arr2[j] = arr[mid + 1 + j];
}

是不正确的动态分配的数组arr2的索引从0开始。
所以你得写

for (int j = 0; j < n; j++) {
    arr2[j] = arr[mid + 1 + j];
}

第二个问题是对while循环使用大括号是不正确的

while (i < m && j < n) {
    if (arr1[i] <= arr2[j]) {
        arr[k] = arr1[i];
        i++;
        k++;
    }

    else {
        arr[k] = arr2[j];
        k++;
        j++;
    }

    while (i < m) {
        arr[k] = arr1[i];
        k++;
        i++;
    }

    while (j < n) {
        arr[k] = arr2[j];
        k++;
        j++;
    }
}

相反,必须有

while (i < m && j < n) {
    if (arr1[i] <= arr2[j]) {
        arr[k] = arr1[i];
        i++;
        k++;
    }

    else {
        arr[k] = arr2[j];
        k++;
        j++;
    }
}

while (i < m) {
    arr[k] = arr1[i];
    k++;
    i++;
}

while (j < n) {
    arr[k] = arr2[j];
    k++;
    j++;
}

也就是说,最后两个while循环应该在第一个while循环之外。
你可以忽略@john的错误答案,它甚至被投票了两次。

相关问题