当前位置: 首页 > 知识库问答 >
问题:

合并排序的比较与排序问题(三)

邬阳
2023-03-14

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

你有两个向量,这个部分应该比较最开始的元素,取较小的元素,然后删除选择的元素,把它放入一个新的向量中。这样做,直到两个向量的大小都为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个答案

徐智渊
2023-03-14

代码可以简化:

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;
}
常甫
2023-03-14

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

常规:合并

对不起,代码很长

使用

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

并操纵它,避免代码复制。

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

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

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

覆盖所有可能的比较结果(两次相等):不再计算,否则将计算
按照Msk的建议,将“移动部件”移动到“正确的合并”之后,请注意,初步检查是可有可无的,只需使用“移动循环”即可。

关于你的代码有很多要说的(从注释开始)——参见C merge实现的代码评审。< br >如果您希望在CR@SE上审查您控制的代码,请务必抓住主题,提出一个好问题。

潘兴朝
2023-03-14

检查其中一个数组是否已耗尽而其他数组是否具有剩余元素应在主 while 循环之外。因此,请尝试将以下两项检查放在外面。

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

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

想想当一个数组有(1)而另一个数组有(2,3)时会发生什么,将1加到排序后的向量上,< code>while(left.size()

 类似资料:
  • 我有以下课程:

  • 在处理接近排序的数组时,哪种算法的快速排序或合并排序性能更好?为什么?我意识到,在这种情况下,其他算法可能会比这些算法表现得更好。

  • 问题内容: [http://jsperf.com/optimized-mergesort-versus- quicksort][1] 为什么这个半缓冲区合并排序的工作速度与quicksort一样快? QuickSort是: 就地虽然会占用递归(堆栈空间) 缓存友好 这一半缓冲区合并排序: 使用Buffer进行合并。 使用递归。 进行较少的比较。 我的问题是,在这种情况下,为什么半缓冲区合并排序与Q

  • 双向合并排序与递归合并排序有何不同? 假设在合并排序中有5个数字需要排序8,9,1,6,4,我们按如下步骤1进行划分:{8,9,1}{6,4} 步骤2:{8,9}{1}{6}{4} 步骤3:{8}{9}{1}{6}{4} 现在合并 步骤4:{8,9}{1}{4,6} 步骤5:{1,8,9}{4,6} 第六步:{1,4,6,8,9} 但在双向合并排序中,我们将数组分为两个元素(但根据维基百科,在合并

  • 事情是这样的。我在做leetcode 164最大间隙。最佳解决方案是桶排序。 这让我对排序问题有了更多的思考。假设我们有如下列表: 2、5、19、444、-14、89、16、77 我认为,我们可以用两个不同的范围来排列这些数字,(min, mid)(mid, max)和mid-应该是min(max-min)/2; 因此我们得到了(-14215)(216444) 我们将min设置为最左侧,max设置

  • 本文向大家介绍合并排序,包括了合并排序的使用技巧和注意事项,需要的朋友参考一下 合并排序技术基于分而治之。我们将整个数据集分成较小的部分,然后按排序顺序将它们合并成较大的部分。在最坏情况下它也非常有效,因为该算法在最坏情况下的时间复杂度也较低。 合并排序技术的复杂性 时间复杂度: 所有情况下为O(n log n) 空间复杂度:  O(n) 输入输出 算法 合并(数组,左,中,右) 输入- 数据集数