我有三个排序数组,如下所示
[{name:"a"}, {name:"b"}, {name:"m"}, {name:"x"}]
[{name:"a"}, {name:"e"}, {name:"i"}, {name:"o"}]
[{name:"g"}, {name:"h"}, {name:"m"}, {name:"n"}]
这些数组根据数组中每个对象的名称属性进行排序。下面是我从Java转换为合并两个排序数组的方法
function mergeSorted(a, b) {
var answer = new Array(a.length + b.length), i = 0, j = 0, k = 0;
while (i < a.length && j < b.length) {
if (a[i].name < b[j].name) {
answer[k] = a[i];
i++;
}else {
answer[k] = b[j];
j++;
}
k++;
}
while (i < a.length) {
answer[k] = a[i];
i++;
k++;
}
while (j < b.length) {
answer[k] = b[j];
j++;
k++;
}
return answer;
}
这里是两个数组的工作小提琴http://jsfiddle.net/euRn5/.什么是最好的方法来实现相同的n个数组,我目前的想法是一个接一个,合并它与以前合并到最后项目,像n=i的东西。这是最好的方法吗?
更快,只合并1次,更灵活(保留重复,自定义比较器):
/* mergeSortedArrays(arrays[, keepDuplicates[, comparator[, thisArg]]])
Merges multiple sorted arrays into a new sorted array.
Arguments:
- arrays: array of sorted arrays to be merged
- keepDuplicates (optional): (true/false) whether to keep duplicate values
Default: false
- comparator (optional): function used to compare values
Default: sort numbers in ascending order
Example comparator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
- thisArg (optional): comparator is bound to thisArg when invoked
Returns: a new sorted array containing all the values from the arrays
*/
function mergeSortedArrays(arrays, keepDuplicates, comparator, thisArg) {
// Coerce to boolean to speed up testings in some javascript engines:
keepDuplicates = !!keepDuplicates;
// By default, sort numbers in ascending order:
if(!comparator) comparator = function(a, b) { return a - b; };
var nb = arrays.length, // Number of arrays to be merged
iter = new Array(nb), // Current position of iteration of each array
next = [], // Keep each array sorted by the value of their next element
length = 0; // The combined length of all arrays
// Populate iter and next:
for(var i = 0, arr; i < nb; i++) {
arr = arrays[i];
iter[i] = 0;
if(arr.length > 0) {
insertNextIndex(next, i, arr[0], comparator, thisArg);
}
length += arr.length;
}
// Insert index of array into next:
function insertNextIndex(next, index, val, comparator, thisArg) {
var i = next.length;
while(i--) { // Reverse loop...
var j = next[i];
if(comparator.call(thisArg, arrays[j][iter[j]], val) >= 0) { // ...until we find a greater value
break;
}
}
next.splice(i + 1, 0, index);
}
var merged = keepDuplicates ? new Array(length) : [],
k = 0, // Iterate over merged
min, val, lastVal;
// First iteration to get a value for lastVal (for duplicate checks):
if(!keepDuplicates && next.length > 0) {
min = next.pop();
arr = arrays[min];
i = iter[min]++;
val = arr[i];
merged[k++] = val;
lastVal = val;
if(++i < arr.length) { // If available, insert next value in next:
insertNextIndex(next, min, arr[i], comparator, thisArg);
}
}
// Merge multiple arrays:
while(next.length > 1) { // While there is still multiple arrays to be merged
min = next.pop();
arr = arrays[min];
i = iter[min]++;
val = arr[i];
if(keepDuplicates || comparator.call(thisArg, lastVal, val) !== 0) {
merged[k++] = val;
lastVal = val;
}
if(++i < arr.length) { // If available, insert next value in next:
insertNextIndex(next, min, arr[i], comparator, thisArg);
}
}
// When there remain only 1 array with unmerged values, use a faster loop:
if(next.length > 0) {
arr = arrays[next[0]];
i = iter[next[0]];
length = arr.length;
while(i < length) { // To the end
val = arr[i++];
if(keepDuplicates || comparator.call(thisArg, lastVal, val) !== 0) {
merged[k++] = val;
lastVal = val;
}
}
}
return merged;
}
一次合并消除了创建中间数组的过程,这需要时间和内存。此外,通过保留每个数组中下一个元素的排序列表(请参见next
array),可以很好地减少比较次数。当数组大小已知时,会预先分配它们以防止动态重新分配(尽管这取决于javascript引擎)。
对于你的情况,我会这样称呼它:
mergeSortedArrays(arrays, true, function(a, b) {
return a.name < b.name ? -1 : 1;
});
注意:如果你有大量的数组,你可能会受益于使用二进制搜索,而不是线性搜索中的插入NextIndex()
。或者从使用二进制堆的下一个
。
鉴于它是current_year
,现在将是:
const mergeAll = (...arrays) => arrays.reduce(mergeSorted);
如果你觉得功能这是一个完美的地方使用减少。
var mergeAll = function(){
return Array.prototype.slice.call(arguments).reduce(mergeSorted);
};
例子:
var a = [{name:"a"}, {name:"b"}, {name:"m"}, {name:"x"}];
var b = [{name:"a"}, {name:"e"}, {name:"i"}, {name:"o"}];
var c = [{name:"g"}, {name:"h"}, {name:"m"}, {name:"n"}];
console.log(mergeAll(a,b,c).map(function(x){return x.name;}));
jsfiddle:http://jsfiddle.net/FeT6m/
我相信这是最标准、最容易理解的代码。。
function mergeArray(arr1, arr2) {
var new_array = [];
var i = 0,
j = 0,
index = 0;
while (new_array.length != (arr1.length + arr2.length) - 1) {
if (arr1[i] < arr2[j]) {
new_array.push(arr1[i]);
i++;
} else {
new_array.push(arr2[j]);
j++;
}
}
return new_array;
}
函数调用:
var merged_array = mergeArray([1,6,9,95], [2,7,10,11,14,18]);
问题是== 将nums1和nums2合并到一个按非递减顺序排序的数组中。 最终排序的数组不应由函数返回,而应存储在数组 nums1 中。为了适应这种情况,nums1 的长度为 m n,其中前 m 个元素表示应合并的元素,最后 n 个元素设置为 0 并应忽略。nums2 的长度为 n。 我的代码中有什么错误??? 您的意见 我的产出 预期产出
我有一个结构数组 我希望合并并按升序排序数组。然而,当我执行合并时,没有任何变化。这是我用来创建struct数组的代码,以及MergeSort的函数调用。最大用户数是我从二叉树中转换节点数得到的整数,它应该是数组的最大数量。 任何提示或提示都将不胜感激! 编辑:当我尝试编写一些printf语句时,我注意到这些值是负数。但是存储在结构中的值是正数。这个错误的原因是什么?
问题内容: 这是在采访中问我的,这是我提供的解决方案: 有没有更有效的方法可以做到这一点? 编辑:更正的长度方法。 问题答案: 稍有改进,但是在主循环之后,当到达另一个输入数组的末尾时,可以用来复制其中一个输入数组的结尾。但是,那不会改变你解决方案的性能特征。
我在Java中实现合并排序算法时遇到了一个问题:我做过合并排序算法,但它不能产生正确的结果。我还从函数中返回排序列表。我怎么也能做到这一点? 下面是我定义的合并排序算法。 合并排序方法: MergeSort函数: 合并算法: 实现比较器功能 我该怎么做?
问题是关于从16:43到23:34的视频中的合并排序http://youtu.be/M814OagXWTI?t=16m43s 在退出左/右排序合并递归后,我不清楚我们是如何合并回这些子数组的。让我们从最底部开始,当我们的元素被分成两个子数组时,一个左子数组称为B,一个右子数组称为C。在16:43左右,我们跳转到合并函数,对数组B和C进行排序,这两个数组只有8和3。合并排序函数(下面的代码)基本上通
我知道类似的问题也有人问过,我也研究过很多网站。我已经尝试使用一些答案,但我的代码仍然不能工作。 我正在经历以前的作业,以帮助建立我的Java知识。请原谅我的代码中的任何错误,我还在学习Java。 假设两个输入数组中的元素都按非递减顺序排序(例如[0,1,2,2]和[1,2,3,3,4,5])。返回的“合并”数组必须保留此属性(例如[0,1,1,2,2,2,3,3,4,5])。 输入和输出都允许重