Javascript Mergesort正在清除数组中的值
我似乎有一个基本的mergesort用于小数组,但在较大的n值时,它似乎正在中断和刮除值。我正在使用助手函数(Javascript Mergesort正在清除数组中的值,javascript,sorting,mergesort,Javascript,Sorting,Mergesort,我似乎有一个基本的mergesort用于小数组,但在较大的n值时,它似乎正在中断和刮除值。我正在使用助手函数(largetest)进行测试 我已经为所有内容添加了条件,验证了切片是否正确(据我所知) helper函数可以帮助创建一个大型数组,发现差异点(取消对控制台日志的注释),并验证长度 我一直在vscode中的quokka.js上运行这个 var mergeSort = function(array) { if (array.length === 1) { return arra
largetest
)进行测试
我已经为所有内容添加了条件,验证了切片是否正确(据我所知)
helper函数可以帮助创建一个大型数组,发现差异点(取消对控制台日志的注释),并验证长度
我一直在vscode中的quokka.js上运行这个
var mergeSort = function(array) {
if (array.length === 1) {
return array;
}
const half = Math.floor(array.length / 2);
let left = array.slice(0, half);
let right = array.slice(half);
var joined = joinArrays(mergeSort(left), mergeSort(right));
return joined;
};
const joinArrays = (array1, array2) => {
var pointer1 = 0;
var pointer2 = 0;
let results = [];
while (array1[pointer1] && array2[pointer2]) {
if (array1[pointer1] <= array2[pointer2]) {
results.push(array1[pointer1]);
pointer1++;
} else if (array1[pointer1] > array2[pointer2]) {
results.push(array2[pointer2]);
pointer2++;
}
}
if (array1[pointer1]) {
results = results.concat(array1.slice(pointer1));
} else if (array2[pointer2]) {
results = results.concat(array2.slice(pointer2));
}
return results;
}
var a = mergeSort([4, 7, 4, 3, 9, 1, 2]);
console.log(a);
var a = mergeSort([48, 56, 2, 34, 98, 75, 42, 21, 3])
console.log(a);
var a = mergeSort([5, 6, 98324, 234, 34, 23, 42520, 234, 4323, 32])
console.log(a);
var a = mergeSort([4, 4, 4, 5, 7, 8, 9, 9, 1, 2, 3, ])
console.log(a);
function largeTest () {
var input = [];
var sorted;
var n = 10;
for (var i = 0; i < n; i++) {
var number = Math.floor(Math.random() * n);
input.push(number);
}
sorted = input.sort(function (a, b) {
return a - b;
});
var result = mergeSort(input);
console.log(result.length, sorted.length) //Why is it shaving numbers?
for (var i = 0; i < n; i++) {
if (result[i] !== sorted[i]) {
//console.log(i, 'result:', result[i], 'sorted:', sorted[i])
}
}
console.log('complete')
}
largeTest()
var mergeSort=函数(数组){
if(array.length==1){
返回数组;
}
const half=数学楼层(array.length/2);
设left=array.slice(0,一半);
设right=array.slice(一半);
var joined=joinArrays(合并排序(左),合并排序(右));
回归加入;
};
常量joinArrays=(array1,array2)=>{
变量指针1=0;
var指针2=0;
让结果=[];
while(array1[pointer1]和&array2[pointer2]){
if(数组1[pointer1]数组2[pointer2]){
结果:push(array2[pointer2]);
指针2++;
}
}
if(数组1[pointer1]){
结果=results.concat(array1.slice(pointer1));
}else if(array2[pointer2]){
结果=results.concat(array2.slice(pointer2));
}
返回结果;
}
var a=合并排序([4,7,4,3,9,1,2]);
控制台日志(a);
var a=mergeSort([48,56,2,34,98,75,42,21,3])
控制台日志(a);
var a=mergeSort([5,698324234,34,2342520234432332])
控制台日志(a);
var a=mergeSort([4,4,4,5,7,8,9,9,1,2,3,]))
控制台日志(a);
函数largeTest(){
var输入=[];
var排序;
var n=10;
对于(变量i=0;i
您的joinArrays()
函数对于合并两个orders数组这样简单的事情看起来非常复杂。尝试用这样的merge()
函数替换joinArrays()
函数:
function merge( left, right, compare = defaultComparer ) {
const merged = [];
let i = 0;
let j = 0;
let k = 0;
// ------------------------------------------------------
// while we have both a left and right item, just compare
// them and pick the lowest to put in the merged array
// ------------------------------------------------------
while ( i < left.length && j < right.length ) {
const cc = compare( left[i], right[j] );
merged[k++] = cc > 0 ? right[j++] : left[i++] ;
}
// ------------------------------------------------------
// if we only have left items... it's easy
// ------------------------------------------------------
while ( i < left.length ) {
merged[k++] = left[i++];
}
// ------------------------------------------------------
// if we only have right items... it's easy
// ------------------------------------------------------
while ( j < right.length ) {
merged[k++] = right[j++];
}
// ------------------------------------------------------
// return the merged array
// ------------------------------------------------------
return merged;
}
function defaultComparer( a, b ) {
return a < b ? -1
: a > b ? +1
: 0
;
}
函数合并(左、右,compare=defaultComparer){
const merged=[];
设i=0;
设j=0;
设k=0;
// ------------------------------------------------------
//虽然我们有左项和右项,但只需比较一下
//然后选择最低点放入合并数组
// ------------------------------------------------------
而(i0?右[j++]:左[i++];
}
// ------------------------------------------------------
//如果我们只剩下一些东西……那就容易了
// ------------------------------------------------------
而(ib?+1
: 0
;
}
您的joinArrays()
函数对于合并两个orders数组这样简单的事情看起来非常复杂。尝试用这样的merge()
函数替换joinArrays()
函数:
function merge( left, right, compare = defaultComparer ) {
const merged = [];
let i = 0;
let j = 0;
let k = 0;
// ------------------------------------------------------
// while we have both a left and right item, just compare
// them and pick the lowest to put in the merged array
// ------------------------------------------------------
while ( i < left.length && j < right.length ) {
const cc = compare( left[i], right[j] );
merged[k++] = cc > 0 ? right[j++] : left[i++] ;
}
// ------------------------------------------------------
// if we only have left items... it's easy
// ------------------------------------------------------
while ( i < left.length ) {
merged[k++] = left[i++];
}
// ------------------------------------------------------
// if we only have right items... it's easy
// ------------------------------------------------------
while ( j < right.length ) {
merged[k++] = right[j++];
}
// ------------------------------------------------------
// return the merged array
// ------------------------------------------------------
return merged;
}
function defaultComparer( a, b ) {
return a < b ? -1
: a > b ? +1
: 0
;
}
函数合并(左、右,compare=defaultComparer){
const merged=[];
设i=0;
设j=0;
设k=0;
// ------------------------------------------------------
//虽然我们有左项和右项,但只需比较一下
//然后选择最低点放入合并数组
// ------------------------------------------------------
而(i0?右[j++]:左[i++];
}
// ------------------------------------------------------
//如果我们只剩下一些东西……那就容易了
// ------------------------------------------------------
而(ib?+1
: 0
;
}
问题的核心在于这一行:
while (array1[pointer1] && array2[pointer2])
您应该在两个数组上循环,只要数组值不为null、未定义或0
,此循环就会执行此操作。这是因为在javascript中读取数组末尾以外的数组元素会返回undefined
,因此测试为false。测试中的小数组不包含空值,因此代码可以工作,但填充伪随机数据的较大数组可能会这样做,每个数组都会导致相应片段的结尾被刮去
您可以通过测试数组长度而不是数组内容来解决此问题:
const joinArrays = (array1, array2) => {
var pointer1 = 0, len1 = array1.length;
var pointer2 = 0, len2 = array2.length;
let results = [];
while (pointer1 < len1 && pointer2 < len2) {
if (array1[pointer1] <= array2[pointer2]) {
results.push(array1[pointer1]);
pointer1++;
} else {
results.push(array2[pointer2]);
pointer2++;
}
}
if (pointer1 < len1) {
results = results.concat(array1.slice(pointer1));
} else if (pointer2 < len2) {
results = results.concat(array2.slice(pointer2));
}
return results;
}
const joinArrays=(array1,array2)=>{
变量指针1=0,len1=array1.length;
变量指针2=0,len2=array2.length;
让结果=[];
while(指针1