如果我使用 2015 之前的方法在函数内部声明参数默认值,则 QuickSort 无限循环,但如果我使用 ES2015 默认参数值,则工作正常

QuickSort infinite loop if I declare param defaults inside function using pre-2015 method, but works fine if I use ES2015 default param values

我一直在尝试实现快速排序功能并使一切正常。但是有一个特点我无法理解或理解为什么。

在第一段代码中,您会看到我已经为 quickSort() 函数声明了一些默认参数值:

function swap(arr, firstIndex, secondIndex) {
  let temp = arr[firstIndex];
  arr[firstIndex] = arr[secondIndex];
  arr[secondIndex] = temp;
}

function pivot(arr, start = 0, end = arr.length - 1) {
  // We are assuming that the pivot is always the first element
  let pivot = arr[start];
  let swapIndex = start;

  for (let i = start + 1; i <= end; i++) {
    if (pivot > arr[i]) {
      swapIndex++;
      swap(arr, swapIndex, i);
    }
  }

  // Swap the starting element with the pivot index
  swap(arr, start, swapIndex);
  return swapIndex;
}

function quickSort(arr, left = 0, right = arr.length - 1) {
  if (left < right) {
    let pivotIndex = pivot(arr, left, right);
    // left
    quickSort(arr, left, pivotIndex - 1);
    // right
    quickSort(arr, pivotIndex + 1, right);
  }
  return arr;
}

在此示例中,它按预期工作正常。但是,如果我要从 quickSort() 中删除 ES2015 默认参数值,而是在函数内部创建默认值,如下所示:

function quickSort(arr, left, right) {
  left = left || 0;
  right = right || arr.length -1;
  if (left < right) {
    let pivotIndex = pivot(arr, left, right);
    // left
    quickSort(arr, left, pivotIndex - 1);
    // right
    quickSort(arr, pivotIndex + 1, right);
  }
  return arr;
}

我遇到无限 loop/Stack 溢出问题,我不明白为什么。据我所知,问题是由第三个参数 - right - 而不是左参数引起的,因为如果我使用 es2015 之前的方法调用左参数,同时离开 right 参数与 ES2015 参数默认方法。

总而言之,我的代码可以正常工作,这很好 - 我只是想尝试更好地理解为什么这会导致问题,因为我以前从未遇到过这样的问题。

谢谢!

问题是当 0 作为 right 传递时,您的两个版本的工作方式不同。 (因为这是一个基本情况,所以你会得到一个无限循环)。

right = right || arr.length -1;
当传入 0 时,

求值到右侧,因为 0 是假的。

另一方面,如果传入 0,则默认参数初始化程序将 0 放入 right,并且只计算 arr.length - 1 表达式 当传入 undefined(或根本没有参数)时。

要复制该行为,您需要在 ES5 中编写

function quickSort(arr, left, right) {
  if (left === undefined) left = 0;
  if (right === undefined) right = arr.length - 1;
  if (left < right) {
    let pivotIndex = pivot(arr, left, right);
    // left
    quickSort(arr, left, pivotIndex - 1);
    // right
    quickSort(arr, pivotIndex + 1, right);
  }
  return arr;
}
const quicksort = ([x, ...rest]) => (!x || x === undefined) ? [] : quicksort(rest.filter(a => a < x))
.concat(x)
.concat(quicksort(rest.filter(a => a >= x)))`

抱歉,这是 ecmascript6 而不是 es5