【问题标题】:Merge sort c++ code returns same order of numbers and does not sort合并排序c ++代码返回相同的数字顺序并且不排序
【发布时间】:2021-09-16 04:43:12
【问题描述】:

代码:

// Merge sort
#include <iostream>
#include <algorithm>
using namespace std;

void Merge(int *A, int *B1, int one, int *B2, int two){
    int *combi = new int[one+two];
    int c = 0, d = 0, x=0;
    while(c < one && d < two){
        cout<<"B1[C] "<<B1[c]<<" B2[d] "<<B2[d]<<endl;
        if(B1[c] < B2[d]){
            combi[x] = B1[c];
            cout<<"combi[x] = "<<combi[x]<<endl;
            c++;
        }
        else{
            combi[x] = B2[d];
            cout<<"combi[x] = "<<combi[x]<<endl;
            d++;
        }
        x++;
    }
    while(c < one){
        combi[x] = B1[c];
        x++;
        c++;
    }
    while(d < two){
        combi[x] = B2[d];
        x++;
        d++;
    }
    

    cout<<"combi is ";
    for(int f = 0; f<one+two; f++) cout<<combi[f]<<' ';
    cout<<endl<<endl;
    
}

void MergeSort(int *A, int n){
    if (n > 1){
        int *B1 = new int[n/2];
        int *B2 = new int[n - n/2];

        for(int x = 0; x < n/2; x++){B1[x] = A[x];}
        for(int x = 0; x < n - n/2; x++){B2[x] = A[x + n/2];}

        cout<<endl<<"B1 is ";
        for(int x = 0; x < n/2; x++)cout<<B1[x]<<' ';
        cout<<endl<<"B2 is ";

        for(int x = 0; x < n - n/2; x++)cout<<B2[x]<<' ';
        cout<<endl;

        MergeSort(B1, n/2);
        MergeSort(B2, n - n/2);

        Merge(A, B1, n/2, B2, n - n/2);
    }
}

int main() {
    int A[ ] = {4,2,6,1};
    MergeSort(A, 4);
    cout<<endl<<endl<<"final A: "<<endl;
    for (int i=0; i < 4; i++) cout << A[i] << " ";
    return 0;
}

输出:

B1 is 4 2 
B2 is 6 1 

B1 is 4 
B2 is 2 
B1[C] 4 B2[d] 2
combi[x] = 2
combi is 2 4 


B1 is 6 
B2 is 1 
B1[C] 6 B2[d] 1
combi[x] = 1
combi is 1 6 

B1[C] 4 B2[d] 6
combi[x] = 4
B1[C] 2 B2[d] 6
combi[x] = 2
combi is 4 2 6 1 



final A: 
4 2 6 1

如您所见,代码在开始时运行顺利,对 4 2 和 6 1 进行排序。然而,这种排序似乎只是暂时的,因为当 B1 和 B2 之后尝试组合时,它们最终变成了相同的数字前。这和我使用指针有关系吗?

在输出中的“combi is 1 6”行之后,代码似乎混乱了。有谁知道发生了什么以及如何解决这个问题?

【问题讨论】:

  • 你在哪里(重新)填充数组A
  • 您也有大量内存泄漏,因为您分配了临时数组但从不删除它们。
  • 除了像筛子漏雨水一样泄露内存,你永远不会真正修改传入的A
  • 您的rubber duck 想知道:为什么您希望A 在调用MergeSort 后以不同的顺序保存元素?

标签: c++ algorithm sorting mergesort


【解决方案1】:

您的代码与Merge 存在问题。在函数的入口处,您希望合并后的数组将写入参数A,但实际上它写入局部变量combi,您不会在任何地方使用它,因此它不会影响结果

要解决这个问题,只需在 Merge 函数中将变量 combi 的每个调用替换为调用 A

结果应该是这样的。 注意:我还添加了释放内存,但总的来说我没有让代码更干净

#include <iostream>
#include <algorithm>
using namespace std;

void Merge(int *A, int *B1, int one, int *B2, int two){
    int c = 0, d = 0, x=0;
    while(c < one && d < two){
        cout<<"B1[C] "<<B1[c]<<" B2[d] "<<B2[d]<<endl;
        if(B1[c] < B2[d]){
            A[x] = B1[c];
            cout<<"combi[x] = "<<A[x]<<endl;
            c++;
        }
        else{
            A[x] = B2[d];
            cout<<"combi[x] = "<<A[x]<<endl;
            d++;
        }
        x++;
    }
    while(c < one){
        A[x] = B1[c];
        x++;
        c++;
    }
    while(d < two){
        A[x] = B2[d];
        x++;
        d++;
    }
    

    cout<<"combi is ";
    for(int f = 0; f<one+two; f++) cout<<A[f]<<' ';
    cout<<endl<<endl;
    
}

void MergeSort(int *A, int n){
    if (n > 1){
        int *B1 = new int[n/2];
        int *B2 = new int[n - n/2];

        for(int x = 0; x < n/2; x++){B1[x] = A[x];}
        for(int x = 0; x < n - n/2; x++){B2[x] = A[x + n/2];}

        cout<<endl<<"B1 is ";
        for(int x = 0; x < n/2; x++)cout<<B1[x]<<' ';
        cout<<endl<<"B2 is ";

        for(int x = 0; x < n - n/2; x++)cout<<B2[x]<<' ';
        cout<<endl;

        MergeSort(B1, n/2);
        MergeSort(B2, n - n/2);

        Merge(A, B1, n/2, B2, n - n/2);

        delete[] B1;
        delete[] B2;
    }
}

int main() {
    int A[ ] = {4,2,6,1};
    MergeSort(A, 4);
    cout<<endl<<endl<<"final A: "<<endl;
    for (int i=0; i < 4; i++) cout << A[i] << " ";
    return 0;
}

PS如果在您的情况下可用,您应该将代码从原始指针切换到 std::vector,从自己的 Merge 函数切换到 std::merge,从逐个复制数组元素切换到std::copy

【讨论】:

  • 请问如果我每次都已经声明它们为“new int”,为什么还要添加“delete[] B1 delete[] B2”?
  • @miloovann new 运算符在内存中的某处分配数组,除非您使用 delete 运算符或取消进程,否则该内存不会释放。因此,如果您的进程应该始终打开,并且您有 new 而没有 delete,那么一段时间后未使用的已分配内存量可能会超过设备上允许的内存量,因此您的程序将无法正常工作。 read more 或谷歌:内存泄漏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
相关资源
最近更新 更多