【问题标题】:C++ Merge Sort returning original vectorC ++合并排序返回原始向量
【发布时间】:2019-12-15 16:25:16
【问题描述】:

我一直在尝试使用 C++ 中的向量进行合并排序,但遇到了一个问题,即任何向量输入都按其原始顺序排序。我在这里基于 geeks4geeks 网站的算法:https://www.geeksforgeeks.org/merge-sort/

到目前为止,我已经花了大约五个小时试图找到错误的根源,似乎在结束合并函数后,向量会以某种方式恢复到其原始格式,但我不确定为什么。任何建议将不胜感激。

#include <iostream>
#include <vector>

using namespace std;


void merge(vector<int> vect, int p, int q, int r) {

    int i, j, k, n1, n2;

    n1 = q - p + 1;
    n2 = r - q;

    vector<int> L, R;

    L.resize(n1);
    R.resize(n2);

    for (i = 0; i < n1; i++) {
        L[i] = vect[p + i];
    }

    for (j = 0; j < n2; j++) {
        R[j] = vect[q + 1 + j];
    }

    i = 0;
    j = 0;
    k = p;


    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            vect[k] = L[i];
            i++;

        }
        else {
            vect[k] = R[j];
            j++;
        }
        k++;
    }


    while (i < n1) {
        vect[k] = L[i];
        i++;
        k++;
    }

    while (j < n2) {
        vect[k] = R[j];
        j++;
        k++;
    }

}



void mergeSort(vector<int> vect, int p, int r) {
    if (p < r) {
        int q = (p + r) / 2;

        mergeSort(vect, p, q);
        mergeSort(vect, q + 1, r);

        merge(vect, p, q, r);


    }
}

int main() {

    vector<int> vect{4,3,5,6,7,8};
    mergeSort(vect, 0, vect.size() - 1);


    for (int i = 0; i < vect.size(); i++) { 
        cout << vect[i] << endl;
    }
}

【问题讨论】:

标签: c++ mergesort


【解决方案1】:

首先你应该知道两者的区别:

  • 按值传递

  • 通过引用传递

    去看看here


其次,您应该更改代码,如下所示:

#include <iostream>
#include <vector>

//using namespace std; forget about it, start using std::whatever_it_is_in_here


void merge(std::vector<int> &vect, int p, int q, int r) // note the & near vect
{
    int i, j, k, n1, n2;

    n1 = q - p + 1;
    n2 = r - q;

    std::vector<int> L, R;

    L.resize(n1);
    R.resize(n2);

    for (i = 0; i < n1; i++) {
        L[i] = vect[p + i];
    }

    for (j = 0; j < n2; j++) {
        R[j] = vect[q + 1 + j];
    }

    i = 0;
    j = 0;
    k = p;


    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            vect[k] = L[i];
            i++;

        }
        else {
            vect[k] = R[j];
            j++;
        }
        k++;
    }


    while (i < n1) {
        vect[k] = L[i];
        i++;
        k++;
    }

    while (j < n2) {
        vect[k] = R[j];
        j++;
        k++;
    }

}



void mergeSort(std::vector<int> &vect, int p, int r) // note the & near vect
{
    if (p < r) {
        int q = (p + r) / 2;

        mergeSort(vect, p, q);
        mergeSort(vect, q + 1, r);

        merge(vect, p, q, r);


    }
}

int main()
{
    std::vector<int> vect{4,3,5,6,7,8};
    mergeSort(vect, 0, vect.size() - 1);


    for (int i = 0; i < vect.size(); i++)
        std::cout << vect[i] << "\n"; // note \n instead of std::endl

    return 0; // you forgot the return statement 
}

  1. 您忘记了 main 函数中的 return 语句
  2. 停止使用使用命名空间标准。检查原因here
  3. 注意"\n" 而不是std::endl。你可以了解更多here

【讨论】:

  • 您也可以在 main 函数中使用基于范围的 for 循环,而不是写 for (int i = 0; i &lt; vect.size(); i++) std::cout &lt;&lt; vect[i] &lt;&lt; "\n"; 它变成 for (int i : vect) std::cout &lt;&lt; i &lt;&lt; "\n";。然而,从 C++11 开始,这是可能的。
  • main() 中省略 return 0 是有效的 C++ 并且已定义行为,请参阅 stackoverflow.com/questions/204476/…。也就是说,无论如何添加它并没有什么坏处。
  • 非常感谢,看来我对 Java 的体验又一次让我失望了!我一定会阅读您提供的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
相关资源
最近更新 更多