遇到Mergesort的比较和订购部分(C ++)的问题

时间:2019-03-17 22:08:50

标签: c++ algorithm sorting mergesort

我已经阅读并理解了Mergesort的工作方式(作为文本),现在我正在尝试对其进行编码。我已经完成了将数据划分的部分(我使用矢量),直到每个部分的大小为1。现在,我为Mergesort中的另一个必需部分编写了代码,我不知道如何调用它,但我只称其为“比较和订购部分”。

您有2个向量,这部分应该比较第一个元素,取较小的元素,然后删除选择的元素并将其放入新的向量中。直到两个向量的大小都为0。

对于长代码我很抱歉,但是我真的不明白为什么代码会忽略最后一个元素? :/ 我添加了一些评论,因此可能更容易遵循我的尝试。

我尝试作为输入

vector<int> v1 = {1,4,5,9};
vector<int> v2 = {2,3,6,7,8};

输出

1 2 3 4 5 6 7 8 0
vector<int> sortit(vector<int> &left, vector<int> &right) {
    vector<int> sorted(left.size() + right.size());
    int i = 0;
    while (left.size() > 0 && right.size() > 0) {
        if (left.at(0) <= right.at(0)) {
            sorted.at(i) = left.at(0);      // putting the smaller element into the new vector
            left.erase(left.begin());       // removing this smaller element from the (old) vector
        }
        else if (right.at(0) <= left.at(0)) {
            sorted.at(i) = right.at(0);     // see comment above
            right.erase(right.begin());     // see comment above
        }
        else if (left.size() <= 0 && right.size() > 0) {    // if left vector has no elements, then take all elements of the right vector and put them into the new vector
            while (right.size() > 0) {
                sorted.at(i) = right.at(0);
                right.erase(right.begin());
            }
        }
        else if (right.size() <= 0 && left.size() > 0) {    // the same just for the right vector
            while (left.size() > 0) {
                sorted.at(i) = left.at(0);
                left.erase(left.begin());
            }
        }
        i++;
    }
    return sorted;
}

3 个答案:

答案 0 :(得分:2)

The check of whether one of the arrays has exhausted and other array has remaining elements should be outside the main while loop. So, try to put the below two checks outside.

else if (left.size() <= 0 && right.size() > 0)    

else if (right.size() <= 0 && left.size() > 0)

Think of what will happen when one array has (1) and other (2,3), On adding 1 to the sorted vector, the while(left.size() > 0 && right.size() > 0) condition is false and the loop breaks. So the other elements are ignored.

答案 1 :(得分:1)

  

不知道如何称呼“比较和订购部分”

按惯例:合并

  

对不起,长代码

使用

themes\your_theme\modules\blocksearch\blocksearch.tpl

并进行操作,避免代码重复。

  

看不到为什么代码会忽略最后一个元素?

first = *left <= *right ? left : right

left.at(0) <= right.at(0)

发现所有可能的比较结果(相等两次):不会再评估right.at(0) <= left.at(0)
suggested by Msk的形式移动“移动部件”以跟随“适当的合并”,请注意,可以进行初步检查-只需使用“移动循环”即可。


关于您的代码,有很多话要说(以注释开头)-有关想法,请参见code reviews of C++ merge implementations
如果您需要代码,可以控制CR @ SE的代码,请确保分别为on topicwrite a Good Question

答案 2 :(得分:1)

代码可以简化:

vector<int> sortit(vector<int> &left, vector<int> &right) {
    vector<int> sorted(left.size() + right.size());
    int i = 0;
    while (1) {
        if (left.at(0) <= right.at(0)) {
            sorted.at(i++) = left.at(0);
            left.erase(left.begin());
            if(left.size == 0){
                do{
                    sorted.at(i++) = right.at(0);
                    right.erase(right.begin());
                }while(right.size != 0);
                return;
            }
        } else {
            sorted.at(i++) = right.at(0);
            right.erase(right.begin());
            if(right.size == 0){
                do{
                    sorted.at(i++) = left.at(0);
                    left.erase(left.begin());
                }while(left.size != 0);
                return;
            }
        }
    }
    return sorted;
}

与其删除矢量元素,不如使用索引:

vector<int> sortit(vector<int> &left, vector<int> &right) {
    vector<int> sorted(left.size() + right.size());
    int i = 0;
    int ll = 0;
    int rr = 0;
    while (1) {
        if (left[ll] <= right[rr]) {
            sorted[i++] = left[ll++];
            if(ll == left.size){
                do{
                    sorted[i++] = right[rr++];
                }while(rr != right.size);
                break;
            }
        } else {
            sorted[i++] = right[rr++];
            if(rr == right.size){
                do{
                    sorted[i++] = left[ll++];
                }while(ll != left.size);
                break;
            }
        }
    }
    return sorted;
}