为什么我在下面的归并排序程序中得到了错误的输出(0 4 0 0 0 0 0 0)?

huangapple go评论79阅读模式
英文:

Why am I getting an incorrect o/p (0 4 0 0 0 0 0 0) for the below merge sort program?

问题

我在这里写了一个归并排序程序,并将值传递到程序中。生成的输出大部分都是零。这是因为在 while 循环中可能存在错误,或者递归逻辑可能不正确吗?

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

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

    // 我们将主数组分成两个数组的长度

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

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

    // 从主数组 arr 复制值到 arr1 和 arr2
    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; // 用于 arr1
    int j = 0; // 用于 arr2
    int k = s; // 因为这是主数组

    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;
}

// 递归函数
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

英文:

I have written a program for merge sort here and passing the values in the program itself. The output that is being generated is mostly zeroes. Is it because of some error in the while loops or is it because my recursive logic is incorrect?

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 &lt; m; i++) {
arr1[i] = arr[x + i];
}
for (int j = mid + 1; j &lt; 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 &lt; m &amp;&amp; j &lt; n) {
if (arr1[i] &lt;= arr2[j]) {
arr[k] = arr1[i];
i++;
k++;
}
else {
arr[k] = arr2[j];
k++;
j++;
}
while (i &lt; m) {
arr[k] = arr1[i];
k++;
i++;
}
while (j &lt; n) {
arr[k] = arr2[j];
k++;
j++;
}
}
delete[] arr1;
delete[] arr2;
}
//the recursive function
void divide(int arr[], int s, int e)
{
if (s &gt;= e)
return;
int mid = s + (e - s) / 2;
divide(arr, s, mid);
divide(arr, mid + 1, e);
merge(arr, s, e);
}
#include &lt;iostream&gt;
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 &lt; n; i++) {
cout &lt;&lt; arr[i] &lt;&lt; &quot; &quot;;
}
return 0;
}

Output for the above code that I am getting is ----> 0 4 0 0 0 0 0 0

答案1

得分: 1

你对变量感到相当困惑。

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 等于零,则不是数组第一部分的元素个数。这只有在 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];
}

等等。我没有指出所有的错误,但你明白了。思考你的变量意义,以便正确使用它们。最好添加一些注释,解释它们的含义,这样你或其他人就不会感到困惑。

英文:

You are getting seriously confused about your variables.

> 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 is the midpoint, and an index into the full array. If is not the number of elements in the first part of the array. That would only be true if s equals zero.

So this is incorrect

> int* arr1 = new int[m];

it should be

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

And this loop is incorrect

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

It should be

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

etc. etc. I haven't pointed out all the mistakes but you get the idea. Think about what your variables mean, so that you use them correctly. It also wouldn't hurt to add some comments explaining what they mean, so you or anyone else doesn't get confused.

答案2

得分: 0

这个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的错误答案,即使被点赞了两次。:)

英文:

This for loop

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

is incorrect. Indices for the dynamically allocated array arr2 start from 0.

So you have to write

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

And the second problem is incorrect using braces for the while loops

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

Instead there must be

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

That is the last two while loops shall be outside the first while loop.

And you may ignore the incorrect answer of @john that was upvoted even two times.:)

huangapple
  • 本文由 发表于 2023年6月26日 20:18:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76556615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定