如何组合2个部分排序的数组?

时间:2011-12-09 22:01:42

标签: c++ algorithm search sorting data-structures

给出2个带有int,A1和A2的数组。 A1长度为L1,A2长度为L1 + L2。 A1和A2的第一个L2元素已经排序。将第一个L2元素组合成A2。 例如

   A1:  1  3  6  0
   A2:  2  5  7  13  10 22 11 
   result: 
   A1 + A2:  1 2 3 5 6 7 13 10 22  11

我的解决方案:

通过将min {A1 [i],A2 [i]}放入数组B [i],O(2 * L2)来选择每个元素 将B复制到A2。 O(L1 + L2)。

不应更改未分类的部分。

有更好的解决方案吗?

感谢

3 个答案:

答案 0 :(得分:2)

int* semiMerge(int*, int, int*, int);

int main() {
  const int A1[] = {1, 3, 6, 0};
  const int A2[] = {2, 5, 7, 13, 10, 22, 11};

  const int L1 = sizeof(A1)/sizeof(int);
  const int L2 = sizeof(A2)/sizeof(int) - L1;

  int* out = semiMerge(A1, L1, A2, L2);
}

int* semiMerge(A1, L1, A2, L2) {
  int* output = new int[L2 + L2 + L1];

  //merge does a sorted combination of the items--both sets must be sorted up to the endpoints;
  //we want to merge only the first L1 results from each array
  std::merge(A1, A1 + L2,
             A2, A2 + L2,
             output);
  //at this point, we have an array of 2*L1 elements, all sorted properly.


  //we want to start looking at the first element we didn't copy from A2,
  //the -1 is to account for the fact that begin() + L1 is the start of the L1+1th slot
  std::copy(A2 + L2,
            A2 + L2 + L1, 
            (output + L2 + L2 - 1));

return output;
}

我选择将A1和A1显示为静态数组,但是如果你将它们作为int*添加到堆分配的数组中,并且如果将完成的数组放在L2中很重要,那么你可以在致电delete[] L2; L2 = out;后说出semiMerge()。我选择不在main中执行此操作,因为我将A2表示为静态数组,而将其替换为out的内容则需要它作为指向动态数组的指针。

答案 1 :(得分:1)

现在我已经弄明白了L1L2是什么:

{
    std::vector<int> B(L2+L2+L1, 0);
    std::merge(A1.begin(), A1.begin()+L2, A2.begin(), A2.begin()+L2, B.begin());
    if (L1 > L2)
        B.insert(B.end(), A2.begin()+L2, A2.end());
    A2.swap(B);
}

B包含[合并的排序部分] [未排序的A2]。这是正确的格式吗?这是您发布的算法。到位(如Nim)速度较慢,但​​占用的内存较少,因此需要权衡利弊。

答案 2 :(得分:0)

  1. 将A1和A2复制到一个数组
  2. std :: inplace_merge with begin,begin + L2,end
  3. (你没有指定没有库函数!);)

    这听起来像是一个家庭作业问题,在提供家庭作业代码之前我通常会犹豫不决。但是看起来这里需要一个例子:

    std::vector<int> A1; // initialize to { 1  3  6  0 }
    std::vector<int> A2; // initialize to { 2  5  7  13  10 22 11 }
    
    // Now assumption here is that we want L2 items from A1, so let's copy
    A2.insert(A2.begin(), A1.begin(), A1.begin() + L2);
    
    // Now A2 contains the sorted range from A1 0 is dropped (?)
    // Now call inplace_merge, this leaves the unsorted segment of A2 alone, and only includes
    // L2 items from A2.
    std::inplace_merge(A2.begin(), A2.begin() + L2, A2.begin() + (2*L2));