簡體   English   中英

合並Java中的n個排序數組

[英]Merging n sorted arrays in Javascript

我有n個(n在1到100之間)排序的數字數組,每個數組都有m個元素(在我的情況下,m約為1000)。 我想將它們合並為單個排序的數組。

我可以想到這樣做的兩種可能性:

1.使用兩個數組合並算法(例如下面的http://www.nczonline.net/blog/2012/10/02/computer-science-and-javascript-merge-sort/的 merge()函數)並將其應用迭代(第一和第二,然后合並第一和第二和第三,依此類推)

  function merge(left, right) {
      var result  = [],
        il      = 0,
        ir      = 0;
      while (il < left.length && ir < right.length){
        if (left[il] < right[ir]){
            result.push(left[il++]);
        } else {
            result.push(right[ir++]);
        }
    }
    return result.concat(left.slice(il)).concat(right.slice(ir));
}
  1. 同時merge()函數泛化為n個數組。 在每次迭代中,我將從尚未處理的n個第一個值中選取最小值,並將其附加到結果中。

就復雜性而言,這兩種算法是否等效? 我覺得兩種算法都在o(m * n)中。 我對嗎 ?

是否有考慮使用一種算法而不是另一種算法的性能? 我覺得1比2更簡單。

使用優先級隊列合並n個數組(例如,基於二進制堆)。
元素總數為m * n,因此算法復雜度為O(m * n * Log(n))。 算法示意圖:

Add numbers 1..n to priority queue, using 1st element of every 
array as sorting key 
(you may also use pairs (first element/array number).
At every step - 
  J = pop_minimum
  add current head of Jth array to result
  move head of Jth array to the right
  if Jth array is not exhausted, insert J in queue (with new sorting key)

第一算法的復雜度是

2*m + 3*m+ 4*m+...+n*m = m * (n*(n-1)/2-1) =  O(n^2 * m)

這是一個老問題,但是為了后代:

兩種算法的確都是O(n * m)。 在算法1中,您必須為每個m數組重新合並。 在算法2中,您只進行了一次大合並,但是從m個數組中選取最小值仍然是線性的。

相反,我要做的是實現合並排序的修改版本以獲取O(mlogn)。

如果有人需要,代碼可以在GitHub https://github.com/jairemix/merge-sorted上找到。

運作方式如下

這個想法是修改算法1並成對而不是線性地成對合並每個數組。

因此,在第一次迭代中,您將array1與array2合並,array3與array4合並,等等。

然后在第二次迭代中,將array1 + array2與array3 + array4,array5 + array6與array7 + array8等合並。

例如:

// starting with:
[1, 8], [4, 14], [2, 5], [3, 7], [0, 6], [10, 12], [9, 15], [11, 13]

  // after iteration 1:
  [1, 4, 8, 14],  [2, 3, 5, 7],   [0, 6, 10, 12],   [9, 11, 13, 15]

    // after iteration 2
    [1, 2, 3, 4, 5, 7, 8, 14],      [0, 6, 9, 10, 11, 12, 13, 15]

        // after iteration 3
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

在JS中:

function mergeSortedArrays(arrays) {

  // while there are still unmerged arrays
  while (arrays.length > 1) {
    const result = [];

    // merge arrays in pairs
    for (let i = 0; i < arrays.length; i += 2) {
      const a1 = arrays[i];
      const a2 = arrays[i + 1];

      // a2 can be undefined if arrays.length is odd, so let's do a check
      const mergedPair = a2 ? merge2SortedArrays(a1, a2) : a1;
      result.push(mergedPair);
    }

    arrays = result;
  }

  // handle the case where no arrays is input
  return arrays.length === 1 ? arrays[0] : [];

}

注意合並排序的相似性。 實際上,在歸並排序中,唯一的區別是n = m,因此您將從m個預排序的數組(每個數組分別包含1個項)開始。 因此,合並排序的O(mlogm)復雜度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM