合并排序不能正确排序(c++)

Merge Sort Not Properly Sorting (C++)

本文关键字:排序 c++ 不能 合并      更新时间:2023-10-16

我正试图实现合并排序,但我的代码似乎缺少了一些东西。代码似乎不正确地附加了每个子排序数组以获得最终结果,并且在某些情况下,添加了元素的副本。

例如,如果我通过函数运行A=[1,3,5,2,4,6],我得到A=[1,2,3,2,4,5,6];在1,2,34,5,6之间似乎有额外的2个。另一个例子是A=[4,2,9,8,11,3]。当"排序"我得到A=[3,4,2,8,3,9,11]。为什么会发生这种情况?

vector<int> mergeSort(vector<int> A)
{
    if(A.size()<=1)
    {
        //print(A);
        return A;
    }
    vector<int> left;
    vector<int> right;
    for(unsigned int i=0; i < A.size()/2; i++)
        left.push_back(A[i]);
    for(unsigned int i=A.size()/2; i < A.size(); i++)
        right.push_back(A[i]);
    vector<int> sortedLeft = mergeSort(left);
    vector<int> sortedRight = mergeSort(right);
    vector<int>::iterator iterL=left.begin();
    vector<int>::iterator iterR;
    vector<int> output;
    while(iterL != left.end())
    {
        iterR=right.begin();
        while(iterR != right.end())
        {
            if(*iterR < *iterL)
            {
                //cout << "Pushing back " << *iterR << endl;
                output.push_back(*iterR);
            }
            iterR++;
        }
        //cout << "Pushing back " << *iterL << endl;
        output.push_back(*iterL);
        iterL++;
    }
    iterR=right.begin();
    while(iterR != right.end())//appends left-over elements in right to output
    {
        if(find(output.begin(), output.end(), *iterR) == output.end())
        {
            //cout << "Pushing back " << *iterR << endl;        
            output.push_back(*iterR);
        }
        iterR++;
    }
    return output;

下面是更新后的while循环:

while(iterL != left.end())
    {
        iterR=right.begin();
        while(iterR != right.end() && *iterR != -1)
        {
            if(*iterR < *iterL)
            {
                //cout << "Pushing back " << *iterR << endl;
                output.push_back(*iterR);
                *iterR = -1;
            }
            iterR++;
        }
        //cout << "Pushing back " << *iterL << endl;
        output.push_back(*iterL);
        iterL++;
    }
    iterR=right.begin();
    while(iterR != right.end())//appends left-over elements in right to output
    {
        if(*iterR != -1)
        {
            output.push_back(*iterR);
        }
        iterR++;
    }

你的主要错误在于这个循环的设计:

while(iterL != left.end())
{
    iterR=right.begin();
    while(iterR != right.end())
    {
        if(*iterR < *iterL)
        {
            //cout << "Pushing back " << *iterR << endl;
            output.push_back(*iterR);
        }
        iterR++;
    }
    //cout << "Pushing back " << *iterL << endl;
    output.push_back(*iterL);
    iterL++;
}

考虑如果左范围是3, 4,右范围是1, 2会发生什么。

  • 在第一次迭代中,它会将正确的元素添加到你的输出中。

  • 在第二次迭代中,它将重置iterR ,以此类推。

您将得到1, 2, 3, 1, 2, 4的输出。

如果你设法正确地保持了右向量中哪个元素被处理的状态,那么关于剩余元素的问题将自行消失。

进一步提示:

::std::merge可能会更好。

你一直在按值传递向量。

你的代码只适用于vector<int>,这在c++中是一个不必要的限制。模板适合晴天