Быстрая сортировка — различия между версиями
(→Худшее время работы) |
(→Среднее время работы) |
||
Строка 60: | Строка 60: | ||
<tex>E[X] = E\left[\sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n} X_{ij}\right] = \sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n} E[X_{ij}] = \sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n} Pr\{z_i</tex> сравнивается с <tex>z_j\}</tex> | <tex>E[X] = E\left[\sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n} X_{ij}\right] = \sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n} E[X_{ij}] = \sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n} Pr\{z_i</tex> сравнивается с <tex>z_j\}</tex> | ||
− | Осталось вычислить величину <tex>Pr\{z_i</tex> сравнивается с <tex>z_j\}</tex> - вероятность того, что <tex>z_i</tex> сравнивается с <tex>z_j</tex>. Поскольку предполагается, что все элементы в массиве различны, то при выборе <tex>x</tex> в качестве опорного элемента впоследствии не будут сравниваться никакие <tex>z_i</tex> и <tex>z_j</tex> для которых <tex>z_i < x < z_j</tex>. С другой стороны, если <tex>z_i</tex> выбран в качестве опорного, то он будет сравниваться с каждым элементом <tex>Z_{ij}</tex> кроме себя самого. Таким образом элементы <tex>z_i</tex> и <tex>z_j</tex> сравниваются тогда и только тогда когда первым в множестве <tex>Z_{ij}</tex> опорным элементом был выбран один из них. | + | Осталось вычислить величину <tex>Pr\{z_i</tex> сравнивается с <tex>z_j\}</tex> {{---}} вероятность того, что <tex>z_i</tex> сравнивается с <tex>z_j</tex>. Поскольку предполагается, что все элементы в массиве различны, то при выборе <tex>x</tex> в качестве опорного элемента впоследствии не будут сравниваться никакие <tex>z_i</tex> и <tex>z_j</tex> для которых <tex>z_i < x < z_j</tex>. С другой стороны, если <tex>z_i</tex> выбран в качестве опорного, то он будет сравниваться с каждым элементом <tex>Z_{ij}</tex> кроме себя самого. Таким образом элементы <tex>z_i</tex> и <tex>z_j</tex> сравниваются тогда и только тогда когда первым в множестве <tex>Z_{ij}</tex> опорным элементом был выбран один из них. |
<tex>Pr\{z_i</tex> сравнивается с <tex>z_j\} = | <tex>Pr\{z_i</tex> сравнивается с <tex>z_j\} = |
Версия 19:34, 4 июня 2012
Быстрая сортировка (qsort, сортировка Хоара) — один из самых известных и широко используемых алгоритмов сортировки. Среднее время работы
, что является асимптотически оптимальным временем работы для алгоритма, основанного на сравнении. Хотя время работы алгоритма для массива из элементов в худшем случае может составить , на практике этот алгоритм является одним из самых быстрых. Кроме того, быстрая сортировка не требует дополнительной памяти.Содержание
Алгоритм
- из массива выбирается некоторый опорный элемент .
- запускается процедура разделения массива, которая перемещает все ключи, меньшие, либо равные , влево от него, а все ключи, большие, либо равные — вправо.
- для обоих подмассивов: если в подмассиве более двух элементов, рекурсивно запускаем для него ту же процедуру..
Псевдокод
<wikitex>
Quicksort(A, p, r) if p < r then q = Partition(A, p, r) Quicksort(A, p, q) Quicksort(A, q + 1, r)
</wikitex> Для сортировки всего массива необходимо выполнить процедуру
.Разбиение массива
Основной шаг алгоритма сортировки — процедура
, которая переставляет элементы массива нужным образом: <wikitex>Partition(A, p, r)
x = A[p]
i = p - 1
j = r + 1
while true
do repeat j = j - 1
until A[j]
x
repeat i = i + 1
until A[i] > x
if i < j
then поменять A[i] и A[j]
else return j
</wikitex>
Асимптотика
Худшее время работы
Предположим, что мы разбиваем массив так, что одна часть содержит
элементов, а вторая — . Поскольку процедура разбиения занимает время , для времени работы получаем соотношение:
.
Мы видим, что при максимально несбалансированном разбиении время работы составляет
. В частности, это происходит, если массив изначально отсортирован.Среднее время работы
Лемма: |
Пусть Х — полное количество сравнений элементов с опорным за время работы сортировки. Тогда время работы сортировки равно . |
Доказательство: |
Нам необходимо вычислить полное количество сравнений. Переименуем элементы массива как , где наименьший по порядку элемент. Также введем множество .Заметим, что сравнеие каждой пары элементов происходит не больше одного раза, так как элемент сравнивается с опорным, а опорный элемент после разбиения больше не будет участвовать в сравнении. Поскольку каждая пара элементов срановается не более одного раза, полное количество сравнений выражается как , где если произошло сравнение и и , если сравнения не произошло. Применим к обоим частям равенства операцию вычисления матожидания и воспользовавшись ее линейностью получим сравнивается с Осталось вычислить величину сравнивается с — вероятность того, что сравнивается с . Поскольку предполагается, что все элементы в массиве различны, то при выборе в качестве опорного элемента впоследствии не будут сравниваться никакие и для которых . С другой стороны, если выбран в качестве опорного, то он будет сравниваться с каждым элементом кроме себя самого. Таким образом элементы и сравниваются тогда и только тогда когда первым в множестве опорным элементом был выбран один из них.сравнивается с первым опорным элементом был или первым опорным элементом был первым опорным элементом был |
Mатожидание времени работы быстрой сортировки будет
.Способы разбиения массива
- При выборе опорного элемента из данного диапазона случайным образом худший случай становится очень маловероятным и ожидаемое время выполнения алгоритма сортировки — O(n lg n).
- Выбирать опорным элементом средний из трех (первого, среднего и последнего элементов). Такой выбор также направлен против худшего случая.
- Разбивать массив не на две, а на три части.
Оптимизация глубины рекурсии до O(logn) в худшем случае
Время работы алгоритма сортировки зависит от того, как разбивается массив на каждом шаге. В случае повторяющихся неудачных разбиений опорным элементом, глубина рекурсии может достичь
а время работы алгоритма . Этого можно избежать, если в цикле разбивать массив, но рекурсивно вызываться только от части, содержащей меньшее число элементов, а большую часть продолжать разбивать в цикле.Ссылки
Литература
- Т. Кормен, Ч. Лейзерсон, Р. Ривест: Алгоритмы: построение и анализ глава 7