Быстрая сортировка бесконечна l oop, если я объявляю параметры по умолчанию внутри функции с использованием метода до 2015 года, но работает нормально, если я использую значения параметров ES2015 по умолчанию - PullRequest
0 голосов
/ 09 марта 2020

Я пытался реализовать функцию быстрой сортировки и все работало. Но есть одна особенность, которую я не могу обернуть головой или понять, почему.

В этом первом блоке кода вы увидите, что я объявил некоторые значения параметров по умолчанию для функции 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;
}

В этом примере все работает нормально, как и ожидалось. Однако, если бы я удалил значения параметров ES2015 по умолчанию из quickSort() и вместо этого создал значения по умолчанию внутри функции, например:

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;
}

, я получаю проблему с бесконечным циклом / переполнением стека и Я не могу понять почему. Из того, что я могу сказать, проблема вызвана третьим параметром - right - а не левым параметром, поскольку код работает нормально, если я вызываю левый параметр с использованием метода pre-es2015, оставляя параметр right с методом по умолчанию для параметров ES2015.

В общем, мой код работает, так что все в порядке - я просто хочу попытаться и лучше понять, почему это может вызвать проблемы, так как я никогда не сталкивался с таким проблема раньше.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 09 марта 2020

Проблема в том, что ваши две версии работают по-разному, когда 0 передается как right. (И поскольку это базовый случай, вы получите бесконечное значение l oop).

right = right || arr.length -1;

вычисляется справа, когда передается 0, поскольку 0 ложно.

Инициализатор параметров по умолчанию с другой стороны помещает 0 в right, если передано 0, и оценивает 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;
}
0 голосов
/ 04 апреля 2020
const quicksort = ([x, ...rest]) => (!x || x === undefined) ? [] : quicksort(rest.filter(a => a < x))
.concat(x)
.concat(quicksort(rest.filter(a => a >= x)))`

Извините, это ecmascript6, а не es5.

...