Search code examples
javascriptalgorithmsortingrecursionmergesort

Merge sort call stack exceeded


I worry that I'm missing something painfully obvious here, but I can't see it. Running this in the chrome console and in node 8.4.0, mergeSort causes a RangeError: Maximum call stack size exceeded for input arrays larger than length 1. The merge function seems to work fine. Here's the code:

"use strict";

function merge(A, B) {
  if (!Array.isArray(A) || !Array.isArray(B)) {
    throw new Error("merge expects both of its arguments to be arrays");
  }

  let result = [];
  let [i, j] = [0, 0];

  while (A[i]) {
    if (B[j]) {
      if (A[i] <= B[j]) {
        result.push(A[i]);
        i++;
      } else {
        while (A[i] >= B[j]) {
          result.push(B[j]);
          j++;
        }
        result.push(A[i]);
        i++;
      }
    } else {
      result.push(A[i]);
      i++;
    }
  }

  while (B[j]) {
    result.push(B[j]);
    j++;
  }

  return result;
}

function mergeSort(A) {
  if (!Array.isArray(A)) {
    throw new Error("mergeSort expects its argument to be an array");
  }

  if (A.length === 1) return A;
  let i = A.slice(Math.floor(A.length / 2));
  let R = A.slice(i);
  let L = A.slice(0, i);
  return merge(mergeSort(R), mergeSort(L));
}

Solution

  • i is not supposed to be an array. You want only

    let i = Math.floor(A.length / 2);
    

    Also your base case is too strict, your function will recurse infinitely on empty arrays as well.