【问题标题】:Having issues which Mergesort's compare and ordering part (c++)合并排序的比较和排序部分有问题(c++)
【发布时间】:2019-03-17 22:08:50
【问题描述】:

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

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

很抱歉代码太长,但我真的不明白为什么最后一个元素被代码忽略了? :/ 我添加了一些 cmets,所以也许更容易遵循我尝试做的事情。

我尝试作为输入

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

【问题讨论】:

标签: c++ algorithm sorting mergesort


【解决方案1】:

检查一个数组是否已经用完而另一个数组是否有剩余元素应该在主while循环之外。 所以,试着把下面的两个检查放在外面。

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

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

想想当一个数组有 (1) 和另一个 (2,3) 时会发生什么,将 1 加到已排序的向量上,while(left.size() &gt; 0 &amp;&amp; right.size() &gt; 0) 条件为假,循环中断。所以其他元素都被忽略了。

【讨论】:

    【解决方案2】:

    不知道怎么称呼[the]“比较和排序部分”

    通常:合并

    抱歉,代码太长了

    使用一个

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

    并对其进行操作,避免代码复制。

    不明白为什么最后一个元素被代码忽略了?

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

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

    涵盖所有可能的比较结果(两次相等):不会再评估 else
    移动“移动部分”以跟随“正确合并”为suggested by Msk,注意初步检查是可有可无的 - 只需使用“移动循环”。


    关于您的代码有很多话要说(从注释开始) - 请参阅 code reviews of C++ merge implementations 了解想法。
    如果您想要在 CR@SE 审查的代码由您控制,请务必使用 on topicwrite a Good Question

    【讨论】:

      【解决方案3】:

      代码可以简化:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 2017-03-28
        • 1970-01-01
        • 2011-02-09
        • 2013-04-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多