Википедия

Быстрая сортировка

Быстрая сортировка, сортировка Хоара (англ. quicksort), часто называемая qsort (по имени в стандартной библиотеке языка Си) — алгоритм сортировки, разработанный английским информатиком Тони Хоаром во время его работы в МГУ в 1960 году.

Быстрая сортировка
image
Визуализация алгоритма быстрой сортировки. Горизонтальные линии обозначают опорные элементы.
Автор Чарлз Энтони Ричард Хоар
Предназначение Алгоритм сортировки
Худшее время O(n2)
Лучшее время O(n log n) (обычное разделение)
или O(n) (разделение на 3 части)
Среднее время O(n log n)
Затраты памяти O(n) вспомогательных
O(log n) вспомогательных (Седжвик 1978)
image Медиафайлы на Викискладе

Один из самых быстрых известных универсальных алгоритмов сортировки массивов: в среднем обменов при упорядочении элементов; из-за наличия ряда недостатков на практике обычно используется с некоторыми доработками.

Общее описание

QuickSort является существенно улучшенным вариантом алгоритма сортировки с помощью прямого обмена (его варианты известны как «Пузырьковая сортировка» и «Шейкерная сортировка»), известного в том числе своей низкой эффективностью. Принципиальное отличие состоит в том, что в первую очередь производятся перестановки на наибольшем возможном расстоянии и после каждого прохода элементы делятся на две независимые группы (таким образом улучшение самого неэффективного прямого метода сортировки дало в результате один из наиболее эффективных улучшенных методов).

Общая идея алгоритма состоит в следующем:

  • Выбрать из массива элемент, называемый опорным. Это может быть любой из элементов массива. От выбора опорного элемента не зависит корректность алгоритма, но в отдельных случаях может сильно зависеть его эффективность (см. ниже).
  • Сравнить все остальные элементы с опорным и переставить их в массиве так, чтобы разбить массив на три непрерывных отрезка, следующих друг за другом: «элементы меньшие опорного», «равные» и «большие».
  • Для отрезков «меньших» и «больших» значений выполнить рекурсивно ту же последовательность операций, если длина отрезка больше единицы.

На практике массив обычно делят не на три, а на две части: например, «меньшие опорного» и «равные и большие»; такой подход в общем случае эффективнее, так как упрощает алгоритм разделения (см. ниже).

Хоар разработал этот метод применительно к машинному переводу; словарь хранился на магнитной ленте, и сортировка слов обрабатываемого текста позволяла получить их переводы за один прогон ленты, без перемотки её назад. Алгоритм был придуман Хоаром во время его пребывания в Советском Союзе, где он обучался в Московском университете компьютерному переводу и занимался разработкой русско-английского разговорника.

Алгоритм

image
Пример быстрой сортировки. Здесь опорным является последний элемент массива (ячейка чёрного цвета), что в отсортированных массивах может приводить к ухудшению производительности

Общий механизм сортировки

Быстрая сортировка относится к алгоритмам «разделяй и властвуй».

Алгоритм состоит из трёх шагов:

  1. Выбрать элемент из массива. Назовём его опорным.
  2. Разбиение: перераспределение элементов в массиве таким образом, что элементы, меньшие опорного, помещаются перед ним, а большие или равные — после.
  3. Рекурсивно применить первые два шага к двум подмассивам слева и справа от опорного элемента. Рекурсия не применяется к массиву, в котором только один элемент или отсутствуют элементы.

В наиболее общем виде алгоритм на псевдокоде (где A — сортируемый массив, а low и high — соответственно, нижняя и верхняя границы сортируемого участка этого массива) выглядит следующим образом:

 algorithm quicksort(A, low, high) is if low < high then p:= partition(A, low, high) quicksort(A, low, p - 1) quicksort(A, p, high) 

Здесь предполагается, что массив A передаётся по ссылке, то есть сортировка происходит «на том же месте», а неописанная функция partition возвращает индекс опорного элемента.

Для выбора опорного элемента и операции разбиения существуют разные подходы, влияющие на производительность алгоритма.

Возможна также следующая реализация быстрой сортировки:

algorithm quicksort(A) is if A is empty return A pivot:= A.pop() (извлечь последний или первый элемент из массива) lA:= A.filter(where e <= pivot) (создать массив с элементами меньше опорного) rA := A.filter(where e > pivot) (создать массив с элементами больше опорного) return quicksort(lA) + [pivot] + quicksort(rA) (вернуть массив, состоящий из отсортированной левой части, опорного и отсортированной правой части). 

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

Выбор опорного элемента

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

Выбор опорного элемента по медиане трёх для разбиения Ломуто:

mid := (low + high) / 2 if A[mid] < A[low] swap A[low] with A[mid] if A[high] < A[low] swap A[low] with A[high] if A[high] < A[mid] swap A[high] with A[mid] pivot:= A[mid] 

Разбиение Ломуто

Данный алгоритм разбиения был предложен Нико Ломуто и популяризован в книгах Бентли (Programming Pearls) и Кормена (Введение в алгоритмы). В данном примере опорным выбирается последний элемент. Алгоритм хранит индекс в переменной i. Каждый раз, когда находится элемент, меньше или равный опорному, индекс увеличивается и элемент вставляется перед опорным. После разбиения опорный элемент окажется в позиции i — на границе между двумя подмножествами. Хоть эта схема разбиения проще и компактнее, чем схема Хоара, она менее эффективна и используется в обучающих материалах. Сложность данной быстрой сортировки возрастает до O(n2), когда массив уже отсортирован или все его элементы равны. Существуют различные методы оптимизации данной сортировки: алгоритмы выбора опорного элемента, использование сортировки вставками на маленьких массивах. В данном примере сортируются элементы массива A от low до high (включительно):

algorithm partition(A, low, high) is pivot := A[high] i := low - 1 for j := low to high do if A[j] ≤ pivot then i := i + 1 if i ≠ j then swap A[i] with A[j] return i + 1 

Сортировка всего массива может быть выполнена с помощью выполнения quicksort(A, 1, length(A)).

Схема Хоара

Данная схема использует два индекса (один в начале массива, другой — в конце), которые приближаются друг к другу, пока не найдётся пара элементов, где один больше опорного и расположен перед ним, а второй — меньше и расположен после. Эти элементы меняются местами. Обмен происходит до тех пор, пока индексы не пересекутся. Алгоритм возвращает последний индекс. Схема Хоара эффективнее схемы Ломуто, так как происходит в среднем в три раза меньше обменов (swap) элементов и разбиение эффективнее, даже когда все элементы равны. Подобно разбиению Ломуто, данная схема также показывает эффективность в O(n2), когда входной массив уже отсортирован. Сортировка с использованием данной схемы нестабильна. Следует заметить, что конечная позиция опорного элемента необязательно совпадает с возвращённым индексом. Псевдокод:

algorithm quicksort(A, lo, hi) is if lo < hi then p:= partition(A, lo, hi) quicksort(A, lo, p) quicksort(A, p + 1, hi) algorithm partition(A, low, high) is pivot:= A[(low + high) / 2] i:= low j:= high loop forever while A[i] < pivot i:= i + 1 while A[j] > pivot j:= j - 1 if i >= j then return j swap A[i++] with A[j--] 

В книге упоминается, что такая реализация алгоритма имеет «много тонких моментов». Вот один из них: выбор в качестве опорного элемента уже существующего элемента в массиве может привести к переполнению стека вызовов из-за того, что номер элемента вычисляется как среднее, а это не целое число. Поэтому логичнее в данном алгоритме выбирать в качестве опорного элемента среднее значение между начальным и конечным элементом:

pivot := A[(low + high) / 2]

Но нет никаких оснований выбирать в качестве опорного элемента A[ (low + high) / 2]. Оптимальным может оказаться любой элемент от low до high с равной вероятностью. Тем более, что A[ (low + high) / 2] — это не среднее значение, а просто элемент из середины массива. Гораздо разумнее выбирать случайный элемент A[ random( low .. high) ]. Это гарантирует, что никто злонамеренно не сможет соорудить массив, который этот алгоритм введёт в очень длинный цикл с переполнением стека. В этом случае вероятность неудачи при сортировке массива из примерно 37 000 элементов, по самой завышенной оценке, составляет примерно 10 в минус 16 степени, что на 3 порядка меньше, чем вероятность выхода из строя компьютера в результате прямого попадания в него метеорита. Неудачей считается число итераций (полного перебора всех элементов массива с целью сравнения и перестановки) более чем 200.

Повторяющиеся элементы

Для улучшения производительности при большом количестве одинаковых элементов в массиве может быть применена процедура разбиения массива на три группы: элементы меньшие опорного, равные ему и больше него (Бентли и Макилрой называют это «толстым разбиением». Данное разбиение используется в функции qsort в седьмой версии Unix). Псевдокод:

algorithm quicksort(A, low, high) is if low < high then p := pivot(A, low, high) left, right := partition(A, p, low, high) // возвращается два значения quicksort(A, low, left) quicksort(A, right, high) 

Быстрая сортировка используется в стандарте языка C++, в частности, в методе sort структуры данных list

# include <iostream> # include <list>  int main() { // quick sort std::list<int> list; const int N = 20; for (int i = 0; i < N; i++) { if (i % 2 == 0) list.push_back(N - i); else list.push_front(N - i); } for (std::list<int>::iterator it = list.begin(); it != list.end(); it++) { std::cout << (*it) << " "; } std::cout << std::endl; list.sort(); for (std::list<int>::iterator it = list.begin(); it != list.end(); it++) { std::cout << (*it) << " "; } //quick sort end std::cout << std::endl; //sort greater list.sort(std::greater<int>()); for (std::list<int>::iterator it = list.begin(); it != list.end(); it++) { std::cout << (*it) << " "; } std::cout << std::endl; //sort greater end  std::cin.ignore(); } 

Оценка сложности алгоритма

Ясно, что операция разделения массива на две части относительно опорного элемента занимает время image. Поскольку все операции разделения, проделываемые на одной глубине рекурсии, обрабатывают разные части исходного массива, размер которого постоянен, суммарно на каждом уровне рекурсии потребуется также image операций. Следовательно, общая сложность алгоритма определяется лишь количеством разделений, то есть глубиной рекурсии. Глубина рекурсии, в свою очередь, зависит от сочетания входных данных и способа определения опорного элемента.

Лучший случай.
В наиболее сбалансированном варианте при каждой операции разделения массив делится на две одинаковые части, следовательно, максимальная глубина рекурсии, при которой размеры обрабатываемых подмассивов достигнут 1, составит image. В результате количество сравнений, совершаемых быстрой сортировкой, было бы равно значению рекурсивного выражения image, что даёт общую сложность алгоритма image.
Среднее.
Среднюю сложность при случайном распределении входных данных можно оценить лишь вероятностно.
Прежде всего необходимо заметить, что в действительности необязательно, чтобы опорный элемент всякий раз делил массив на две одинаковых части. Например, если на каждом этапе будет происходить разделение на массивы длиной 75 % и 25 % от исходного, глубина рекурсии будет равна image, а это по-прежнему даёт сложность image. Вообще, при любом фиксированном соотношении между левой и правой частями разделения сложность алгоритма будет той же, только с разными константами.
Будем считать «удачным» разделением такое, при котором опорный элемент окажется среди центральных 50 % элементов разделяемой части массива; ясно, что вероятность удачи при случайном распределении элементов составляет 0,5. При удачном разделении размеры выделенных подмассивов составят не менее 25 % и не более 75 % от исходного. Поскольку каждый выделенный подмассив так же будет иметь случайное распределение, все эти рассуждения применимы к любому этапу сортировки и любому исходному фрагменту массива.
Удачное разделение даёт глубину рекурсии не более image. Поскольку вероятность удачи равна 0,5, для получения image удачных разделений в среднем потребуется image рекурсивных вызовов, чтобы опорный элемент k раз оказался среди центральных 50 % массива. Применяя эти соображения, можно заключить, что в среднем глубина рекурсии не превысит image, что равно image А, поскольку на каждом уровне рекурсии по-прежнему выполняется не более image операций, средняя сложность составит image.
Худший случай.
В самом несбалансированном варианте каждое разделение даёт два подмассива размерами 1 и image, то есть при каждом рекурсивном вызове больший массив будет на 1 короче, чем в предыдущий раз. Такое может произойти, если в качестве опорного на каждом этапе будет выбран элемент либо наименьший, либо наибольший из всех обрабатываемых. При простейшем выборе опорного элемента — первого или последнего в массиве — такой эффект даст уже отсортированный (в прямом или обратном порядке) массив, для среднего или любого другого фиксированного элемента «массив худшего случая» также может быть специально подобран. В этом случае потребуется image операций разделения, а общее время работы составит image операций, то есть сортировка будет выполняться за квадратичное время. Но количество обменов и, соответственно, время работы — это не самый большой его недостаток. Хуже то, что в таком случае глубина рекурсии при выполнении алгоритма достигнет n, что будет означать n-кратное сохранение адреса возврата и локальных переменных процедуры разделения массивов. Для больших значений n худший случай может привести к исчерпанию памяти (переполнению стека) во время работы программы.

Достоинства и недостатки

Достоинства:

  • Один из самых быстродействующих (на практике) из алгоритмов внутренней сортировки общего назначения.
  • Алгоритм очень короткий: запомнив основные моменты, его легко написать «из головы», невелика константа при image.
  • С модификациями требует лишь image дополнительной памяти в виде стека (неулучшенный рекурсивный алгоритм — в худшем случае image стека).
  • Хорошо сочетается с механизмами кэширования и виртуальной памяти.
  • Допускает естественное распараллеливание (сортировка выделенных подмассивов в параллельно выполняющихся подпроцессах).
  • Допускает эффективную модификацию для сортировки по нескольким ключам (в частности — для сортировки строк): благодаря тому, что в процессе разделения автоматически выделяется отрезок элементов, равных опорному, этот отрезок можно сразу же сортировать по следующему ключу.
  • Работает на связных списках и других структурах с последовательным доступом, допускающих эффективный проход как от начала к концу, так и от конца к началу.

Недостатки:

  • Сильно деградирует по скорости (до image) в худшем или близком к нему случае, что может случиться при неудачных входных данных.
  • Прямая реализация в виде функции с двумя рекурсивными вызовами может привести к ошибке переполнения стека, так как в худшем случае ей может потребоваться сделать image вложенных рекурсивных вызовов.
  • Неустойчив.

Улучшения

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

  • Проблема неустойчивости решается путём расширения ключа исходным индексом элемента в массиве. В случае равенства основных ключей сравнение производится по индексу, исключая, таким образом, возможность изменения взаимного положения равных элементов. Эта модификация не бесплатна — она требует дополнительно O(n) памяти и одного полного прохода по массиву для сохранения исходных индексов.
  • Деградация по скорости в случае неудачного набора входных данных решается по двум разным направлениям: снижение вероятности возникновения худшего случая путём специального выбора опорного элемента и применение различных технических приёмов, обеспечивающих устойчивую работу на неудачных входных данных. Для первого направления:
  • Выбор среднего элемента. Устраняет деградацию для предварительно отсортированных данных, но оставляет возможность случайного появления или намеренного подбора «плохого» массива.
  • Выбор медианы из трёх элементов: первого, среднего и последнего. Снижает вероятность возникновения худшего случая, по сравнению с выбором среднего элемента.
  • Случайный выбор. Вероятность случайного возникновения худшего случая становится исчезающе малой, а намеренный подбор — практически неосуществимым. Ожидаемое время выполнения алгоритма сортировки составляет O(n log n).
Недостаток всех усложнённых методов выбора опорного элемента — дополнительные накладные расходы; впрочем, они не так велики.
  • Во избежание отказа программы из-за большой глубины рекурсии могут применяться следующие методы:
  • При достижении нежелательной глубины рекурсии переходить на сортировку другими методами, не требующими рекурсии. Примером такого подхода является алгоритм Introsort или некоторые реализации быстрой сортировки в библиотеке STL. Можно заметить, что алгоритм очень хорошо подходит для такого рода модификаций, так как на каждом этапе позволяет выделить непрерывный отрезок исходного массива, предназначенный для сортировки, и то, каким методом будет отсортирован этот отрезок, никак не влияет на обработку остальных частей массива.
  • Модификация алгоритма, устраняющая одну ветвь рекурсии: вместо того, чтобы после разделения массива вызывать рекурсивно процедуру разделения для обоих найденных подмассивов, рекурсивный вызов делается только для меньшего подмассива, а больший обрабатывается в цикле в пределах этого же вызова процедуры. С точки зрения эффективности в среднем случае разницы практически нет: накладные расходы на дополнительный рекурсивный вызов и на организацию сравнения длин подмассивов и цикла — примерно одного порядка. Зато глубина рекурсии ни при каких обстоятельствах не превысит image, а в худшем случае вырожденного разделения она вообще будет не более 2 — вся обработка пройдёт в цикле первого уровня рекурсии. Применение этого метода не спасёт от катастрофического падения производительности, но переполнения стека не будет.
  • Разбивать массив не на две, а на три части.

См. также

  • Список алгоритмов сортировки

Примечания

  1. Hoare C. A. R. Algorithm 64: Quicksort (англ.) // Communications of the ACM — New York City: Association for Computing Machinery, 1961. — Vol. 4, Iss. 7. — P. 321. — ISSN 0001-0782; 1557-7317 — doi:10.1145/366622.366644
  2. Очевидно, что после такой перестановки для получения отсортированного массива не понадобится перемещать ни один из элементов между получившимися отрезками, то есть достаточно будет произвести сортировку «меньшего» и «большего» отрезков как самостоятельных массивов.
  3. Sedgewick, Robert. Algorithms In C: Fundamentals, Data Structures, Sorting, Searching, Parts 1-4 (англ.). — 3. — [англ.], 1998. — ISBN 978-81-317-1291-7.
  4. Jon Bentley. Programming Pearls (англ.). — Addison-Wesley Professional, 1999.
  5. Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Quicksort // Алгоритмы: построение и анализ = Introduction to Algorithms / Под ред. И. В. Красикова. — 3-е изд. — М.: Вильямс, 2013. — С. 170–190. — ISBN 5-8459-1794-8.
  6. Hoare, C. a. R. Quicksort (англ.) // [англ.] : journal. — 1962. — 1 January (vol. 5, no. 1). — P. 10—16. — ISSN 0010-4620. — doi:10.1093/comjnl/5.1.10. Архивировано 22 мая 2014 года.
  7. Quicksort Partitioning: Hoare vs. Lomuto. cs.stackexchange.com. Дата обращения: 3 августа 2015.
  8. Bentley, Jon L.; McIlroy, M. Douglas. Engineering a sort function (англ.) // Software—Practice and Experience. — 1993. — Vol. 23, no. 11. — P. 1249—1265. — doi:10.1002/spe.4380231105. Архивировано 16 января 2014 года.
  9. Dual Pivot Quicksort. Дата обращения: 8 декабря 2015. Архивировано 4 марта 2016 года.

Литература

  • Левитин А. В. Глава 4. Метод декомпозиции: Быстрая сортировка // Алгоритмы. Введение в разработку и анализМ.: Вильямс, 2006. — С. 174—179. — 576 с. — ISBN 978-5-8459-0987-9
  • Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Глава 7. Быстрая сортировка // Алгоритмы: построение и анализ = Introduction to Algorithms / Под ред. И. В. Красикова. — 2-е изд. — М.: Вильямс, 2005. — С. 198—219. — ISBN 5-8459-0857-4.

Ссылки

  • Анимированное сравнение алгоритмов сортировки
  • Визуализаторы: , , [3]
  • Динамическая визуализация 7 алгоритмов сортировки с открытым исходным кодом

Википедия, чтение, книга, библиотека, поиск, нажмите, истории, книги, статьи, wikipedia, учить, информация, история, скачать, скачать бесплатно, mp3, видео, mp4, 3gp, jpg, jpeg, gif, png, картинка, музыка, песня, фильм, игра, игры, мобильный, телефон, Android, iOS, apple, мобильный телефон, Samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Сеть, компьютер, Информация о Быстрая сортировка, Что такое Быстрая сортировка? Что означает Быстрая сортировка?

Bystraya sortirovka sortirovka Hoara angl quicksort chasto nazyvaemaya qsort po imeni v standartnoj biblioteke yazyka Si algoritm sortirovki razrabotannyj anglijskim informatikom Toni Hoarom vo vremya ego raboty v MGU v 1960 godu Bystraya sortirovkaVizualizaciya algoritma bystroj sortirovki Gorizontalnye linii oboznachayut opornye elementy Avtor Charlz Entoni Richard HoarPrednaznachenie Algoritm sortirovkiHudshee vremya O n2 Luchshee vremya O n log n obychnoe razdelenie ili O n razdelenie na 3 chasti Srednee vremya O n log n Zatraty pamyati O n vspomogatelnyh O log n vspomogatelnyh Sedzhvik 1978 Mediafajly na Vikisklade Odin iz samyh bystryh izvestnyh universalnyh algoritmov sortirovki massivov v srednem O nlog n displaystyle O n log n obmenov pri uporyadochenii n displaystyle n elementov iz za nalichiya ryada nedostatkov na praktike obychno ispolzuetsya s nekotorymi dorabotkami Obshee opisanieV razdele ne hvataet ssylok na istochniki sm rekomendacii po poisku Informaciya dolzhna byt proveryaema inache ona mozhet byt udalena Vy mozhete otredaktirovat statyu dobaviv ssylki na avtoritetnye istochniki v vide snosok 21 fevralya 2023 QuickSort yavlyaetsya sushestvenno uluchshennym variantom algoritma sortirovki s pomoshyu pryamogo obmena ego varianty izvestny kak Puzyrkovaya sortirovka i Shejkernaya sortirovka izvestnogo v tom chisle svoej nizkoj effektivnostyu Principialnoe otlichie sostoit v tom chto v pervuyu ochered proizvodyatsya perestanovki na naibolshem vozmozhnom rasstoyanii i posle kazhdogo prohoda elementy delyatsya na dve nezavisimye gruppy takim obrazom uluchshenie samogo neeffektivnogo pryamogo metoda sortirovki dalo v rezultate odin iz naibolee effektivnyh uluchshennyh metodov Obshaya ideya algoritma sostoit v sleduyushem Vybrat iz massiva element nazyvaemyj opornym Eto mozhet byt lyuboj iz elementov massiva Ot vybora opornogo elementa ne zavisit korrektnost algoritma no v otdelnyh sluchayah mozhet silno zaviset ego effektivnost sm nizhe Sravnit vse ostalnye elementy s opornym i perestavit ih v massive tak chtoby razbit massiv na tri nepreryvnyh otrezka sleduyushih drug za drugom elementy menshie opornogo ravnye i bolshie Dlya otrezkov menshih i bolshih znachenij vypolnit rekursivno tu zhe posledovatelnost operacij esli dlina otrezka bolshe edinicy Na praktike massiv obychno delyat ne na tri a na dve chasti naprimer menshie opornogo i ravnye i bolshie takoj podhod v obshem sluchae effektivnee tak kak uproshaet algoritm razdeleniya sm nizhe Hoar razrabotal etot metod primenitelno k mashinnomu perevodu slovar hranilsya na magnitnoj lente i sortirovka slov obrabatyvaemogo teksta pozvolyala poluchit ih perevody za odin progon lenty bez peremotki eyo nazad Algoritm byl priduman Hoarom vo vremya ego prebyvaniya v Sovetskom Soyuze gde on obuchalsya v Moskovskom universitete kompyuternomu perevodu i zanimalsya razrabotkoj russko anglijskogo razgovornika AlgoritmPrimer bystroj sortirovki Zdes opornym yavlyaetsya poslednij element massiva yachejka chyornogo cveta chto v otsortirovannyh massivah mozhet privodit k uhudsheniyu proizvoditelnostiObshij mehanizm sortirovki Bystraya sortirovka otnositsya k algoritmam razdelyaj i vlastvuj Algoritm sostoit iz tryoh shagov Vybrat element iz massiva Nazovyom ego opornym Razbienie pereraspredelenie elementov v massive takim obrazom chto elementy menshie opornogo pomeshayutsya pered nim a bolshie ili ravnye posle Rekursivno primenit pervye dva shaga k dvum podmassivam sleva i sprava ot opornogo elementa Rekursiya ne primenyaetsya k massivu v kotorom tolko odin element ili otsutstvuyut elementy V naibolee obshem vide algoritm na psevdokode gde A sortiruemyj massiv a low i high sootvetstvenno nizhnyaya i verhnyaya granicy sortiruemogo uchastka etogo massiva vyglyadit sleduyushim obrazom algorithm quicksort A low high is if low lt high then p partition A low high quicksort A low p 1 quicksort A p high Zdes predpolagaetsya chto massiv A peredayotsya po ssylke to est sortirovka proishodit na tom zhe meste a neopisannaya funkciya partition vozvrashaet indeks opornogo elementa Dlya vybora opornogo elementa i operacii razbieniya sushestvuyut raznye podhody vliyayushie na proizvoditelnost algoritma Vozmozhna takzhe sleduyushaya realizaciya bystroj sortirovki algorithm quicksort A is if A is empty return A pivot A pop izvlech poslednij ili pervyj element iz massiva lA A filter where e lt pivot sozdat massiv s elementami menshe opornogo rA A filter where e gt pivot sozdat massiv s elementami bolshe opornogo return quicksort lA pivot quicksort rA vernut massiv sostoyashij iz otsortirovannoj levoj chasti opornogo i otsortirovannoj pravoj chasti Na praktike ona ne ispolzuetsya a sluzhit lish v obrazovatelnyh celyah tak kak ispolzuet dopolnitelnuyu pamyat chego mozhno izbezhat Vybor opornogo elementa V rannih realizaciyah kak pravilo opornym vybiralsya pervyj element chto snizhalo proizvoditelnost na otsortirovannyh massivah Dlya uluchsheniya effektivnosti mozhet vybiratsya srednij sluchajnyj element ili dlya bolshih massivov mediana pervogo srednego i poslednego elementov Mediana vsej posledovatelnosti yavlyaetsya optimalnym opornym elementom no eyo vychislenie slishkom trudoyomko dlya ispolzovaniya v sortirovke Vybor opornogo elementa po mediane tryoh dlya razbieniya Lomuto mid low high 2 if A mid lt A low swap A low with A mid if A high lt A low swap A low with A high if A high lt A mid swap A high with A mid pivot A mid Razbienie Lomuto Dannyj algoritm razbieniya byl predlozhen Niko Lomuto i populyarizovan v knigah Bentli Programming Pearls i Kormena Vvedenie v algoritmy V dannom primere opornym vybiraetsya poslednij element Algoritm hranit indeks v peremennoj i Kazhdyj raz kogda nahoditsya element menshe ili ravnyj opornomu indeks uvelichivaetsya i element vstavlyaetsya pered opornym Posle razbieniya opornyj element okazhetsya v pozicii i na granice mezhdu dvumya podmnozhestvami Hot eta shema razbieniya proshe i kompaktnee chem shema Hoara ona menee effektivna i ispolzuetsya v obuchayushih materialah Slozhnost dannoj bystroj sortirovki vozrastaet do O n2 kogda massiv uzhe otsortirovan ili vse ego elementy ravny Sushestvuyut razlichnye metody optimizacii dannoj sortirovki algoritmy vybora opornogo elementa ispolzovanie sortirovki vstavkami na malenkih massivah V dannom primere sortiruyutsya elementy massiva A ot low do high vklyuchitelno algorithm partition A low high is pivot A high i low 1 for j low to high do if A j pivot then i i 1 if i j then swap A i with A j return i 1 Sortirovka vsego massiva mozhet byt vypolnena s pomoshyu vypolneniya quicksort A 1 length A Shema HoaraDannaya shema ispolzuet dva indeksa odin v nachale massiva drugoj v konce kotorye priblizhayutsya drug k drugu poka ne najdyotsya para elementov gde odin bolshe opornogo i raspolozhen pered nim a vtoroj menshe i raspolozhen posle Eti elementy menyayutsya mestami Obmen proishodit do teh por poka indeksy ne peresekutsya Algoritm vozvrashaet poslednij indeks Shema Hoara effektivnee shemy Lomuto tak kak proishodit v srednem v tri raza menshe obmenov swap elementov i razbienie effektivnee dazhe kogda vse elementy ravny Podobno razbieniyu Lomuto dannaya shema takzhe pokazyvaet effektivnost v O n2 kogda vhodnoj massiv uzhe otsortirovan Sortirovka s ispolzovaniem dannoj shemy nestabilna Sleduet zametit chto konechnaya poziciya opornogo elementa neobyazatelno sovpadaet s vozvrashyonnym indeksom Psevdokod algorithm quicksort A lo hi is if lo lt hi then p partition A lo hi quicksort A lo p quicksort A p 1 hi algorithm partition A low high is pivot A low high 2 i low j high loop forever while A i lt pivot i i 1 while A j gt pivot j j 1 if i gt j then return j swap A i with A j V knige upominaetsya chto takaya realizaciya algoritma imeet mnogo tonkih momentov Vot odin iz nih vybor v kachestve opornogo elementa uzhe sushestvuyushego elementa v massive mozhet privesti k perepolneniyu steka vyzovov iz za togo chto nomer elementa vychislyaetsya kak srednee a eto ne celoe chislo Poetomu logichnee v dannom algoritme vybirat v kachestve opornogo elementa srednee znachenie mezhdu nachalnym i konechnym elementom pivot A low high 2 No net nikakih osnovanij vybirat v kachestve opornogo elementa A low high 2 Optimalnym mozhet okazatsya lyuboj element ot low do high s ravnoj veroyatnostyu Tem bolee chto A low high 2 eto ne srednee znachenie a prosto element iz serediny massiva Gorazdo razumnee vybirat sluchajnyj element A random low high Eto garantiruet chto nikto zlonamerenno ne smozhet soorudit massiv kotoryj etot algoritm vvedyot v ochen dlinnyj cikl s perepolneniem steka V etom sluchae veroyatnost neudachi pri sortirovke massiva iz primerno 37 000 elementov po samoj zavyshennoj ocenke sostavlyaet primerno 10 v minus 16 stepeni chto na 3 poryadka menshe chem veroyatnost vyhoda iz stroya kompyutera v rezultate pryamogo popadaniya v nego meteorita Neudachej schitaetsya chislo iteracij polnogo perebora vseh elementov massiva s celyu sravneniya i perestanovki bolee chem 200 Povtoryayushiesya elementy Dlya uluchsheniya proizvoditelnosti pri bolshom kolichestve odinakovyh elementov v massive mozhet byt primenena procedura razbieniya massiva na tri gruppy elementy menshie opornogo ravnye emu i bolshe nego Bentli i Makilroj nazyvayut eto tolstym razbieniem Dannoe razbienie ispolzuetsya v funkcii qsort v sedmoj versii Unix Psevdokod algorithm quicksort A low high is if low lt high then p pivot A low high left right partition A p low high vozvrashaetsya dva znacheniya quicksort A low left quicksort A right high Bystraya sortirovka ispolzuetsya v standarte yazyka C v chastnosti v metode sort struktury dannyh list include lt iostream gt include lt list gt int main quick sort std list lt int gt list const int N 20 for int i 0 i lt N i if i 2 0 list push back N i else list push front N i for std list lt int gt iterator it list begin it list end it std cout lt lt it lt lt std cout lt lt std endl list sort for std list lt int gt iterator it list begin it list end it std cout lt lt it lt lt quick sort end std cout lt lt std endl sort greater list sort std greater lt int gt for std list lt int gt iterator it list begin it list end it std cout lt lt it lt lt std cout lt lt std endl sort greater end std cin ignore Ocenka slozhnosti algoritmaYasno chto operaciya razdeleniya massiva na dve chasti otnositelno opornogo elementa zanimaet vremya O n displaystyle O n Poskolku vse operacii razdeleniya prodelyvaemye na odnoj glubine rekursii obrabatyvayut raznye chasti ishodnogo massiva razmer kotorogo postoyanen summarno na kazhdom urovne rekursii potrebuetsya takzhe O n displaystyle O n operacij Sledovatelno obshaya slozhnost algoritma opredelyaetsya lish kolichestvom razdelenij to est glubinoj rekursii Glubina rekursii v svoyu ochered zavisit ot sochetaniya vhodnyh dannyh i sposoba opredeleniya opornogo elementa Luchshij sluchaj V naibolee sbalansirovannom variante pri kazhdoj operacii razdeleniya massiv delitsya na dve odinakovye chasti sledovatelno maksimalnaya glubina rekursii pri kotoroj razmery obrabatyvaemyh podmassivov dostignut 1 sostavit log2 n displaystyle log 2 n V rezultate kolichestvo sravnenij sovershaemyh bystroj sortirovkoj bylo by ravno znacheniyu rekursivnogo vyrazheniya Cn 2 Cn 2 n displaystyle C n 2 cdot C n 2 n chto dayot obshuyu slozhnost algoritma O n log2 n displaystyle O n cdot log 2 n Srednee Srednyuyu slozhnost pri sluchajnom raspredelenii vhodnyh dannyh mozhno ocenit lish veroyatnostno Prezhde vsego neobhodimo zametit chto v dejstvitelnosti neobyazatelno chtoby opornyj element vsyakij raz delil massiv na dve odinakovyh chasti Naprimer esli na kazhdom etape budet proishodit razdelenie na massivy dlinoj 75 i 25 ot ishodnogo glubina rekursii budet ravna log4 3 n displaystyle log 4 3 n a eto po prezhnemu dayot slozhnost O nlog n displaystyle O n log n Voobshe pri lyubom fiksirovannom sootnoshenii mezhdu levoj i pravoj chastyami razdeleniya slozhnost algoritma budet toj zhe tolko s raznymi konstantami Budem schitat udachnym razdeleniem takoe pri kotorom opornyj element okazhetsya sredi centralnyh 50 elementov razdelyaemoj chasti massiva yasno chto veroyatnost udachi pri sluchajnom raspredelenii elementov sostavlyaet 0 5 Pri udachnom razdelenii razmery vydelennyh podmassivov sostavyat ne menee 25 i ne bolee 75 ot ishodnogo Poskolku kazhdyj vydelennyj podmassiv tak zhe budet imet sluchajnoe raspredelenie vse eti rassuzhdeniya primenimy k lyubomu etapu sortirovki i lyubomu ishodnomu fragmentu massiva Udachnoe razdelenie dayot glubinu rekursii ne bolee log4 3 n displaystyle log 4 3 n Poskolku veroyatnost udachi ravna 0 5 dlya polucheniya k displaystyle k udachnyh razdelenij v srednem potrebuetsya 2 k displaystyle 2 cdot k rekursivnyh vyzovov chtoby opornyj element k raz okazalsya sredi centralnyh 50 massiva Primenyaya eti soobrazheniya mozhno zaklyuchit chto v srednem glubina rekursii ne prevysit 2 log4 3 n displaystyle 2 cdot log 4 3 n chto ravno O log n displaystyle O log n A poskolku na kazhdom urovne rekursii po prezhnemu vypolnyaetsya ne bolee O n displaystyle O n operacij srednyaya slozhnost sostavit O nlog n displaystyle O n log n Hudshij sluchaj V samom nesbalansirovannom variante kazhdoe razdelenie dayot dva podmassiva razmerami 1 i n 1 displaystyle n 1 to est pri kazhdom rekursivnom vyzove bolshij massiv budet na 1 koroche chem v predydushij raz Takoe mozhet proizojti esli v kachestve opornogo na kazhdom etape budet vybran element libo naimenshij libo naibolshij iz vseh obrabatyvaemyh Pri prostejshem vybore opornogo elementa pervogo ili poslednego v massive takoj effekt dast uzhe otsortirovannyj v pryamom ili obratnom poryadke massiv dlya srednego ili lyubogo drugogo fiksirovannogo elementa massiv hudshego sluchaya takzhe mozhet byt specialno podobran V etom sluchae potrebuetsya n 1 displaystyle n 1 operacij razdeleniya a obshee vremya raboty sostavit i 0n n i O n2 displaystyle textstyle sum i 0 n n i O n 2 operacij to est sortirovka budet vypolnyatsya za kvadratichnoe vremya No kolichestvo obmenov i sootvetstvenno vremya raboty eto ne samyj bolshoj ego nedostatok Huzhe to chto v takom sluchae glubina rekursii pri vypolnenii algoritma dostignet n chto budet oznachat n kratnoe sohranenie adresa vozvrata i lokalnyh peremennyh procedury razdeleniya massivov Dlya bolshih znachenij n hudshij sluchaj mozhet privesti k ischerpaniyu pamyati perepolneniyu steka vo vremya raboty programmy Dostoinstva i nedostatkiDostoinstva Odin iz samyh bystrodejstvuyushih na praktike iz algoritmov vnutrennej sortirovki obshego naznacheniya Algoritm ochen korotkij zapomniv osnovnye momenty ego legko napisat iz golovy nevelika konstanta pri nlog n displaystyle n log n S modifikaciyami trebuet lish O log n displaystyle O log n dopolnitelnoj pamyati v vide steka neuluchshennyj rekursivnyj algoritm v hudshem sluchae O n displaystyle O n steka Horosho sochetaetsya s mehanizmami keshirovaniya i virtualnoj pamyati Dopuskaet estestvennoe rasparallelivanie sortirovka vydelennyh podmassivov v parallelno vypolnyayushihsya podprocessah Dopuskaet effektivnuyu modifikaciyu dlya sortirovki po neskolkim klyucham v chastnosti dlya sortirovki strok blagodarya tomu chto v processe razdeleniya avtomaticheski vydelyaetsya otrezok elementov ravnyh opornomu etot otrezok mozhno srazu zhe sortirovat po sleduyushemu klyuchu Rabotaet na svyaznyh spiskah i drugih strukturah s posledovatelnym dostupom dopuskayushih effektivnyj prohod kak ot nachala k koncu tak i ot konca k nachalu Nedostatki Silno degradiruet po skorosti do O n2 displaystyle O n 2 v hudshem ili blizkom k nemu sluchae chto mozhet sluchitsya pri neudachnyh vhodnyh dannyh Pryamaya realizaciya v vide funkcii s dvumya rekursivnymi vyzovami mozhet privesti k oshibke perepolneniya steka tak kak v hudshem sluchae ej mozhet potrebovatsya sdelat O n displaystyle O n vlozhennyh rekursivnyh vyzovov Neustojchiv UluchsheniyaUluchsheniya algoritma napravleny v osnovnom na ustranenie ili smyagchenie vysheupomyanutyh nedostatkov vsledstvie chego vse ih mozhno razdelit na tri gruppy pridanie algoritmu ustojchivosti ustranenie degradacii proizvoditelnosti specialnym vyborom opornogo elementa i zashita ot perepolneniya steka vyzovov iz za bolshoj glubiny rekursii pri neudachnyh vhodnyh dannyh Problema neustojchivosti reshaetsya putyom rasshireniya klyucha ishodnym indeksom elementa v massive V sluchae ravenstva osnovnyh klyuchej sravnenie proizvoditsya po indeksu isklyuchaya takim obrazom vozmozhnost izmeneniya vzaimnogo polozheniya ravnyh elementov Eta modifikaciya ne besplatna ona trebuet dopolnitelno O n pamyati i odnogo polnogo prohoda po massivu dlya sohraneniya ishodnyh indeksov Degradaciya po skorosti v sluchae neudachnogo nabora vhodnyh dannyh reshaetsya po dvum raznym napravleniyam snizhenie veroyatnosti vozniknoveniya hudshego sluchaya putyom specialnogo vybora opornogo elementa i primenenie razlichnyh tehnicheskih priyomov obespechivayushih ustojchivuyu rabotu na neudachnyh vhodnyh dannyh Dlya pervogo napravleniya Vybor srednego elementa Ustranyaet degradaciyu dlya predvaritelno otsortirovannyh dannyh no ostavlyaet vozmozhnost sluchajnogo poyavleniya ili namerennogo podbora plohogo massiva Vybor mediany iz tryoh elementov pervogo srednego i poslednego Snizhaet veroyatnost vozniknoveniya hudshego sluchaya po sravneniyu s vyborom srednego elementa Sluchajnyj vybor Veroyatnost sluchajnogo vozniknoveniya hudshego sluchaya stanovitsya ischezayushe maloj a namerennyj podbor prakticheski neosushestvimym Ozhidaemoe vremya vypolneniya algoritma sortirovki sostavlyaet O n log n Nedostatok vseh uslozhnyonnyh metodov vybora opornogo elementa dopolnitelnye nakladnye rashody vprochem oni ne tak veliki Vo izbezhanie otkaza programmy iz za bolshoj glubiny rekursii mogut primenyatsya sleduyushie metody Pri dostizhenii nezhelatelnoj glubiny rekursii perehodit na sortirovku drugimi metodami ne trebuyushimi rekursii Primerom takogo podhoda yavlyaetsya algoritm Introsort ili nekotorye realizacii bystroj sortirovki v biblioteke STL Mozhno zametit chto algoritm ochen horosho podhodit dlya takogo roda modifikacij tak kak na kazhdom etape pozvolyaet vydelit nepreryvnyj otrezok ishodnogo massiva prednaznachennyj dlya sortirovki i to kakim metodom budet otsortirovan etot otrezok nikak ne vliyaet na obrabotku ostalnyh chastej massiva Modifikaciya algoritma ustranyayushaya odnu vetv rekursii vmesto togo chtoby posle razdeleniya massiva vyzyvat rekursivno proceduru razdeleniya dlya oboih najdennyh podmassivov rekursivnyj vyzov delaetsya tolko dlya menshego podmassiva a bolshij obrabatyvaetsya v cikle v predelah etogo zhe vyzova procedury S tochki zreniya effektivnosti v srednem sluchae raznicy prakticheski net nakladnye rashody na dopolnitelnyj rekursivnyj vyzov i na organizaciyu sravneniya dlin podmassivov i cikla primerno odnogo poryadka Zato glubina rekursii ni pri kakih obstoyatelstvah ne prevysit log2 n displaystyle log 2 n a v hudshem sluchae vyrozhdennogo razdeleniya ona voobshe budet ne bolee 2 vsya obrabotka projdyot v cikle pervogo urovnya rekursii Primenenie etogo metoda ne spasyot ot katastroficheskogo padeniya proizvoditelnosti no perepolneniya steka ne budet Razbivat massiv ne na dve a na tri chasti Imeetsya vikiuchebnik po teme Realizacii algoritmov Sortirovka Bystraya Sm takzheSpisok algoritmov sortirovkiPrimechaniyaHoare C A R Algorithm 64 Quicksort angl Communications of the ACM New York City Association for Computing Machinery 1961 Vol 4 Iss 7 P 321 ISSN 0001 0782 1557 7317 doi 10 1145 366622 366644 Ochevidno chto posle takoj perestanovki dlya polucheniya otsortirovannogo massiva ne ponadobitsya peremeshat ni odin iz elementov mezhdu poluchivshimisya otrezkami to est dostatochno budet proizvesti sortirovku menshego i bolshego otrezkov kak samostoyatelnyh massivov Sedgewick Robert Algorithms In C Fundamentals Data Structures Sorting Searching Parts 1 4 angl 3 angl 1998 ISBN 978 81 317 1291 7 Jon Bentley Programming Pearls angl Addison Wesley Professional 1999 Kormen T Lejzerson Ch Rivest R Shtajn K Quicksort Algoritmy postroenie i analiz Introduction to Algorithms Pod red I V Krasikova 3 e izd M Vilyams 2013 S 170 190 ISBN 5 8459 1794 8 Hoare C a R Quicksort angl angl journal 1962 1 January vol 5 no 1 P 10 16 ISSN 0010 4620 doi 10 1093 comjnl 5 1 10 Arhivirovano 22 maya 2014 goda Quicksort Partitioning Hoare vs Lomuto neopr cs stackexchange com Data obrasheniya 3 avgusta 2015 Bentley Jon L McIlroy M Douglas Engineering a sort function angl Software Practice and Experience 1993 Vol 23 no 11 P 1249 1265 doi 10 1002 spe 4380231105 Arhivirovano 16 yanvarya 2014 goda Dual Pivot Quicksort neopr Data obrasheniya 8 dekabrya 2015 Arhivirovano 4 marta 2016 goda LiteraturaLevitin A V Glava 4 Metod dekompozicii Bystraya sortirovka Algoritmy Vvedenie v razrabotku i analiz M Vilyams 2006 S 174 179 576 s ISBN 978 5 8459 0987 9 Kormen T Lejzerson Ch Rivest R Shtajn K Glava 7 Bystraya sortirovka Algoritmy postroenie i analiz Introduction to Algorithms Pod red I V Krasikova 2 e izd M Vilyams 2005 S 198 219 ISBN 5 8459 0857 4 SsylkiAnimirovannoe sravnenie algoritmov sortirovki Vizualizatory 3 Dinamicheskaya vizualizaciya 7 algoritmov sortirovki s otkrytym ishodnym kodomV state est spisok istochnikov no ne hvataet snosok Bez snosok slozhno opredelit iz kakogo istochnika vzyato kazhdoe otdelnoe utverzhdenie Vy mozhete uluchshit statyu prostaviv snoski na istochniki podtverzhdayushie informaciyu Svedeniya bez snosok mogut byt udaleny 4 yanvarya 2015

NiNa.Az

NiNa.Az - Абсолютно бесплатная система, которая делится для вас информацией и контентом 24 часа в сутки.
Взгляните
Закрыто