Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mergesort正在清除数组中的值_Javascript_Sorting_Mergesort - Fatal编程技术网

Javascript Mergesort正在清除数组中的值

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

我似乎有一个基本的mergesort用于小数组,但在较大的n值时,它似乎正在中断和刮除值。我正在使用助手函数(
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