[英]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));
}
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.