Какая временная сложность у быстрой сортировки в худшем случае

Ответ

Быстрая сортировка (QuickSort) в худшем случае имеет временную сложность O(n²). Это происходит, когда опорный элемент (pivot) выбирается неудачно (например, минимальный или максимальный элемент), и массив разбивается на подмассивы размером n-1 и 0 на каждом шаге.

Пример худшего случая:

const arr = [1, 2, 3, 4, 5]; // Уже отсортированный массив
function quickSort(arr) {
  if (arr.length <= 1) return arr;
  const pivot = arr[0]; // Выбираем первый элемент (худший выбор)
  const left = [];
  const right = [];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) left.push(arr[i]);
    else right.push(arr[i]);
  }
  return [...quickSort(left), pivot, ...quickSort(right)];
}

Чтобы избежать худшего случая, используют рандомизированный выбор pivot или медиану трёх элементов. В среднем QuickSort работает за O(n log n).

Ответ 18+ 🔞

А, слушай, про эту быструю сортировку, QuickSort, вспомнил. Ну, в теории она же быстрая, да? А на практике, если накосячить с выбором этого самого pivot'а — опорного элемента, ёпта, — то можно такую дичь получить, что массив из пяти элементов будешь сортировать дольше, чем я вчера бутылку водки искал.

Вот смотри, представь себе уже отсортированный массив, например, [1, 2, 3, 4, 5]. И если твоя функция, как последний распиздяй, тупо берёт первый элемент за pivot, то что получается? На каждом шаге левый подмассив пустой, а правый — это всё, что осталось, кроме самого pivot'а. И она будет вызывать сама себя на массиве размером n-1, потом n-2, и так до пизды. Сложность выходит O(n²), хуле! Прямо как пузырьковая сортировка, только с претензией на крутость. Ебать мои старые костыли, вот это облом.

const arr = [1, 2, 3, 4, 5]; // Уже отсортированный массив
function quickSort(arr) {
  if (arr.length <= 1) return arr;
  const pivot = arr[0]; // Выбираем первый элемент (худший выбор)
  const left = [];
  const right = [];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) left.push(arr[i]);
    else right.push(arr[i]);
  }
  return [...quickSort(left), pivot, ...quickSort(right)];
}

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

Но нормальные люди, они не такие ебланы. Чтобы избежать этого худшего случая, используют рандомизированный выбор pivot'а — типа, берём случайный элемент из массива, и шанс постоянно попадать на минимум или максимум резко падает. Или ещё круче — медиана трёх: смотришь на первый, средний и последний элемент, и берёшь тот, который между ними. Тогда в среднем, сука, эта сортировка летает за O(n log n), как и положено уважающей себя быстрой сортировке. Так что, если вдруг твой QuickSort тормозит как вязкая жопа — первым делом смотри на выбор pivot'а, там обычно и собака зарыта.