Быстрая сортировка: различия между версиями
Ctrlalt (обсуждение | вклад) (→Ссылки) |
Ctrlalt (обсуждение | вклад) Нет описания правки |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 8: | Строка 8: | ||
Если в качестве опорного выбирать любой фиксированный элемент, всегда можно составить контртест, на котором время работы будет квадратичным. Чтобы избежать худшего случая, требуется в качестве опорного выбирать случайный элемент в рассматриваемом диапазоне. Можно показать, что ожидаемая сложность при этом составит O(NlogN); константа у быстрой сортировки, как правило, меньше, чем у других сортировок с подобной асимптотической сложностью. | Если в качестве опорного выбирать любой фиксированный элемент, всегда можно составить контртест, на котором время работы будет квадратичным. Чтобы избежать худшего случая, требуется в качестве опорного выбирать случайный элемент в рассматриваемом диапазоне. Можно показать, что ожидаемая сложность при этом составит O(NlogN); константа у быстрой сортировки, как правило, меньше, чем у других сортировок с подобной асимптотической сложностью. | ||
minstd_rand generator; | |||
void quickSort(vector<int> &a, int l, int r) { | void quickSort(vector<int> &a, int l, int r) { | ||
if (l >= r) | if (l >= r) | ||
Строка 17: | Строка 19: | ||
int i = l + 1, j = r; | int i = l + 1, j = r; | ||
while (1) { | while (1) { | ||
while (i <= | while (i <= j && a[i] < a[l]) | ||
i++; | i++; | ||
while (j | while (i <= j && a[j] > a[l]) | ||
j--; | j--; | ||
if (i > | if (i > j) | ||
break; | break; | ||
swap(a[i++], a[j--]); | swap(a[i++], a[j--]); | ||
Строка 34: | Строка 36: | ||
minstd_rand generator; | minstd_rand generator; | ||
{{Changed|int}} quickSort(vector<int> &a, int l, int r, {{Changed|1=int k}}) { | {{Changed|int}} quickSort(vector<int> &a, int l, int r, {{Changed|1=int k}}) { | ||
uniform_int_distribution<int> distribution(l, r); | uniform_int_distribution<int> distribution(l, r); |
Текущая версия от 02:35, 11 ноября 2022
Алгоритм
Выбираем в массиве опорный элемент. За Θ(N) делим массив на части: (<= опорного), (опорный), (>= опорного). Левую и правую части сортируем рекурсивно.
В лучшем случае, если опорный элемент будет делить массив примерно пополам, получим сложность O(NlogN), как у сортировки слиянием.
С другой стороны, если опорный элемент каждый раз выбирать неудачно (близко к минимуму или максимуму), то одна из половин будет почти пустой, а сложность деградирует до O(N2).
Если в качестве опорного выбирать любой фиксированный элемент, всегда можно составить контртест, на котором время работы будет квадратичным. Чтобы избежать худшего случая, требуется в качестве опорного выбирать случайный элемент в рассматриваемом диапазоне. Можно показать, что ожидаемая сложность при этом составит O(NlogN); константа у быстрой сортировки, как правило, меньше, чем у других сортировок с подобной асимптотической сложностью.
minstd_rand generator; void quickSort(vector<int> &a, int l, int r) { if (l >= r) return; uniform_int_distribution<int> distribution(l, r); swap(a[l], a[distribution(generator)]); int i = l + 1, j = r; while (1) { while (i <= j && a[i] < a[l]) i++; while (i <= j && a[j] > a[l]) j--; if (i > j) break; swap(a[i++], a[j--]); } swap(a[l], a[j]); quickSort(a, l, j - 1); quickSort(a, j + 1, r); }
K-я порядковая статистика за O(N)
minstd_rand generator; int quickSort(vector<int> &a, int l, int r, int k) { uniform_int_distribution<int> distribution(l, r); swap(a[l], a[distribution(generator)]); int i = l + 1, j = r; while (1) { while (i <= r && a[i] < a[l]) i++; while (j > l && a[j] > a[l]) j--; if (i >= j) break; swap(a[i++], a[j--]); } swap(a[l], a[j]); if (k < j) return quickSort(a, l, j - 1, k); if (k == j) return a[j]; else return quickSort(a, j + 1, r, k); }
Ссылки
Теория:
- neerc.ifmo.ru/wiki — Быстрая сортировка
- neerc.ifmo.ru/wiki — Поиск k-ой порядковой статистики
- algorithmica.org — Сортировки
- algs4.cs.princeton.edu/lectures — 2.3 Quicksort
- Brilliant.org — Quicksort
Демонстрация:
Код:
- indy256/codelibrary/java/sort/Quicksort.java
- indy256/codelibraryjava/sort/NthElement.java
- ADJA/algos/Other/QuickSort.cpp
- algs4.cs.princeton.edu/code — quicksort, quicksort with 3-way partitioning, optimized quicksort
Задачи: