如何组合两个部分排序的数组

How to combine 2 partially sorted arrays?

本文关键字:数组 两个 排序 何组合 组合      更新时间:2023-10-16

给定两个数组,分别为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

my solutions:

将min {A1[i], A2[i]}放入数组B[i], 0 (2 * L2)将B复制到A2。O(l1 + l2)

未排序的部分不应更改。

有更好的解决方案吗?

谢谢

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* s到堆分配数组,并且如果重要的是将完成的数组放置在L2中,那么您可以在调用semiMerge()后说delete[] L2; L2 = out;。我选择不这样做,主要是因为我将A2表示为静态数组,而将其切换为out的内容将要求它是指向动态数组的指针。

现在我已经弄清楚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]。这是正确的格式吗?这是你发布的算法。In place(如Nim)速度较慢,但使用的内存较少,因此这是一种权衡。

  1. 将A1和A2复制到一个数组
  2. std::inplace_merge with begin, begin + L2, end

(你没有指定任何库函数!);)

这听起来像一个家庭作业问题,在为家庭作业提供代码之前,我通常会犹豫。然而,这里似乎需要一个示例:

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