Опубликован: 05.01.2015 | Доступ: свободный | Студентов: 2178 / 0 | Длительность: 63:16:00
Лекция 7:

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

Характеристики производительности быстрой СОРТИРОВКИ

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

Лемма 7.1. Быстрая сортировка в худшем случае выполняет порядка N2/2 сравнений.

Как только что было показано, количество сравнений, выполняемых при сортировке уже упорядоченного файла, равно

N + (N - 1) + (N - 2) + ... + 2 + 1 = (N + 1) N/ 2.

Все разбиения также являются вырожденными и для обратно упорядоченных файлов, и для других редко встречающихся на практике файлов (см. упражнение 7.6). $\blacksquare$

Это поведение означает не только то, что время выполнения будет порядка N2/2 , но также и то, что объем памяти, требуемой для обслуживания рекурсии, будет порядка N (см. раздел 7.3), что неприемлемо для больших файлов. К счастью, существуют сравнительно простые способы резко уменьшить вероятность того, что этот наихудший случай встретится в типичных применениях программы.

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

CN = 2CN/2 + N

Член 2CN/2 соответствует затратам на сортировку двух подфайлов, а N соответствует затратам на проверку каждого элемента при использовании того или другого индекса разбиения. Мы уже знаем из "Рекурсия и деревья" , что это рекуррентное уравнение имеет решение $$C_{N}\approx NlgN$$

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

Лемма 7.2. Быстрая сортировка в среднем выполняет порядка 2NlnN сравнений. Точная рекуррентная формула для количества сравнений, выполняемых во время быстрой сортировки N случайно распределенных различных элементов, имеет вид $$C_{N}=N+1+\dfrac{1}{N}\sum \limits_{1\leq k\leq N} (C_{k-1}+C_{N-k}) {\ для\ }N\geq 2$$

при С1 = С0 = 0 . Член N + 1 учитывает затраты на выполнение операций сравнения центрального элемента с каждым из остальных (и еще двумя, когда индексы пересекаются); остальное следует из того факта, что каждый элемент k может быть центральным с вероятностью 1/k, после чего остаются случайно упорядоченные файлы с размерами k - 1 и N- k.

Это рекуррентное уравнение, хоть и выглядит сложным, на самом деле решается легко, в три шага. Во-первых, С0 + С1 + ... + CN-1 равно CN-1 + CN-2 + ... + С0 , следовательно, $$C_{N}=N+1+\dfrac{2}{N}\sum \limits_{1\leq k\leq N}C_{k-1}$$

Во-вторых, можно избавиться от суммы, умножив обе части равенства на N и вычтя эту же формулу для N- 1:

NCN - (N - 1)CN-1 = N (N + 1) - (N - 1)N + 2CN-1 .

Эта формула упрощается до рекуррентного соотношения

NCN = (N + 1)CN-1 + 2N .

В третьих, разделив обе части на N (N + 1), получим соотношение, которое далее сворачивается:


  \begin{align*}
  \dfrac{C_{N}}{N+1}&=\dfrac{C_{N-1}}{N}+\dfrac{2}{N+1}\\
  &=\dfrac{C_{N-2}}{N-1}+\dfrac{2}{N}+\dfrac{2}{N+1}\\
  &=\vdots\\
  &=\dfrac{C_{2}}{3}+\sum \limits_{3\leq k\leq N}\dfrac{2}{k+1}
  \end{align*}

Этот точный ответ почти равен сумме, легко аппроксимируемой интегралом (см. раздел 2.3 "Принципы анализа алгоритмов" ): $$\dfrac{C_{N}}{N+1}\approx 2\sum \limits_{1\leq k\leq N}\dfrac{1}{k}\approx 2\int\limits_{1}\limits^{N}\dfrac{1}{x}dx=2\ln{N}$$

откуда и вытекает нужный результат. Обратите внимание, что $2N lnN \approx 1,39N lgN$, так что среднее количество операций сравнения приблизительно лишь примерно на 39% больше, чем в лучшем случае. $\blacksquare$

Данный анализ предполагает, что сортируемый файл содержит случайно упорядоченные записи с различными ключами, однако, как показано на рис. 7.4, реализации в программах 7.1 и 7.2 могут работать медленно в тех случаях, когда ключи не обязательно различны и не обязательно расположены в случайном порядке ( рис. 7.4). Если программа сортировки будет использоваться многократно или будет применяться для очень большого файла (или, в особенности, если она должна использоваться как стандартная библиотечная сортировка, которая будет применяться для сортировки файлов с неизвестными характеристиками), тогда следует рассмотреть несколько усовершенствований, предлагаемых в разделах 7.5 и 7.6, которые значительно уменьшают вероятность появления на практике неудачных случаев, а также уменьшают среднее время выполнения сортировки примерно на 20%.

 Динамические характеристики быстрой сортировки при обработке различных видов файлов

Рис. 7.4. Динамические характеристики быстрой сортировки при обработке различных видов файлов

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

Упражнения

7.6. Приведите шесть файлов из 10 элементов, для которых быстрая сортировка (программа 7.1) выполняет такое же количество сравнений, что и в худшем случае (когда все элементы упорядочены).

7.7. Напишите программу для расчета точного значения CN и сравните это точное значение с аппроксимацией 2N lnN для N = 103, 104, 105 и 106 .

7.8. Сколько примерно операций сравнения выполнит быстрая сортировка (программа 7.1) при сортировке файла из N одинаковых элементов?

7.9. Сколько примерно операций сравнения выполнит быстрая сортировка (программа 7.1) при сортировке файла, состоящего из N элементов, ключи которых могут иметь только два различных значения (к элементов с одним значением и N- к элементов с другим)?

7.10. Напишите программу, генерирующую файл, наилучший для быстрой сортировки, т.е. такой файл из N различных элементов, что каждое его разбиение порождает подфайлы, отличающиеся по размеру не более чем на 1.

Бактыгуль Асаинова
Бактыгуль Асаинова

Здравствуйте прошла курсы на тему Алгоритмы С++. Но не пришел сертификат и не доступен.Где и как можно его скаачат?

Александра Боброва
Александра Боброва

Я прошла все лекции на 100%.

Но в https://www.intuit.ru/intuituser/study/diplomas ничего нет.

Что делать? Как получить сертификат?