两个数组的就地合并

时间:2010-12-29 09:56:08

标签: algorithm

我们有一个大小 m + n 的数组,其中 m 元素是 按排序顺序显示,以及第二个大小为 n 的数组,再次按排序顺序排列。我们 希望它们都被排序并出现在第一个数组中。没有第三个阵列 应该被给予。

示例:

   1, 3, 55, 66, 77, _, _, _ 
   5, 9, 20 

答案是:

   1, 3, 5, 9, 20, 55, 66, 77 

4 个答案:

答案 0 :(得分:27)

进行常规合并排序,但反过来先比较最大的数字,然后将(反向)存储到第一个数组的末尾。这样,您正在合并的元素永远不会被覆盖(如果您暂时考虑它,这很容易看到。)

答案 1 :(得分:1)

将第一个数组的内容移动到第一个数组的末尾,以便空元素现在位于开头。然后像往常一样将两个序列合并到第一个数组中。

答案 2 :(得分:1)

就地基本上要求我们只使用“常量”的内存量,这不会随着不同的输入数组大小而变化。但是,问题本身会分配额外的内存量,这与两个输入数组中的一个的大小相同,在最坏的情况下是O(n)内存。这基本上使“就地”的想法毫无意义......

这个问题可能更好地表达为“没有额外记忆的合并”,这是对其真实意图的更精确描述......

答案 3 :(得分:1)

    // merge the elements in B[] to A[], starting from the last one
    void merge(int A[], int m, int B[], int n) {
       // m-1 and n-1 represent the current element index in A[] and B[] respectively
      while (n > 0) { // there are still elements in B[] not merged
          if (m > 0 && A[m-1] > B[n-1]) { // current element in A[] > current element in B[]
            A[m+n-1] = A[m-1]; // move current element of A[] to its right position
            --m; // decrease current element index of A[]
          }
         else { // current element in A[] <= current element in B[]
            A[m+n-1] = B[n-1]; // move current element in B[] to its right position
            --n; // decrease current element index of B[]
         }
      }
   }