Нижняя граница на heapsort? - PullRequest
14 голосов
/ 04 января 2011

Общеизвестно, что для heapsort время выполнения в худшем случае составляет Ω (n lg n), но мне сложно понять, почему это так.В частности, первый шаг heapsort (создание max-heap) занимает время Θ (n).Затем следует n кучи удалений.Я понимаю, почему каждое удаление кучи занимает время O (LG N);восстановление баланса кучи включает в себя операцию всплытия, которая занимает время O (h) на высоте кучи и h = O (lg n).Однако я не вижу, почему этот второй шаг должен принимать Ω (n lg n).Кажется, что любое отдельное удаление кучи не обязательно приведет к тому, что узел, перемещенный наверх, будет пузыриться по всему дереву.

Мой вопрос - кто-нибудь знает хорошее доказательство с нижней границей для лучшегоповедение heapsort?

Ответы [ 3 ]

17 голосов
/ 05 января 2011

Так что я немного покопался, и похоже, что этот результат на самом деле довольно недавний! Первое доказательство нижней границы, которое я могу найти, относится к 1992 году, хотя сам гиппорт был изобретен в 1964 году.

Формальное нижнее доказательство связано с работой Шаффера и Седжвика "Анализ Heapsort". Вот слегка перефразированная версия доказательства, в которой пропущены некоторые технические детали.

Для начала предположим, что n = 2 k - 1 для некоторого k, что гарантирует, что у нас полная двоичная куча. Я покажу, как обращаться с этим делом отдельно позже. Поскольку у нас 2 k - 1 элементов, первый проход heapsort в & Theta; (n) создаст кучу высоты k. Теперь рассмотрим первую половину очереди из этой кучи, которая удаляет из кучи 2 k-1 узлов. Первое ключевое наблюдение заключается в том, что если вы берете начальную кучу, а затем отмечаете здесь все узлы, которые на самом деле в конечном итоге становятся заблокированными, они образуют поддерево кучи (т. Е. У каждого обрабатываемого узла есть родительский объект, который также освобождается от очереди). Вы можете видеть это, потому что если бы это было не так, то был бы какой-то узел, родительский элемент которого (большего размера) не был удален из очереди, хотя сам узел был снят, что означает, что значения вышли из строя.

Теперь рассмотрим, как узлы этого дерева распределяются по куче. Если вы пометите уровни кучи 0, 1, 2, ..., k - 1, то будет некоторое количество этих узлов на уровнях 0, 1, 2, ..., k - 2 (то есть все, кроме нижнего уровня дерева). Для того, чтобы эти узлы были выведены из кучи, их нужно поменять местами до корня и поменять местами только на один уровень за раз. Это означает, что одним из способов нижнего ограничения времени выполнения heapsort является подсчет количества перестановок, необходимых для передачи всех этих значений в корень. На самом деле, это именно то, что мы собираемся сделать.

Первый вопрос, на который нам нужно ответить, - сколько самых больших 2 k-1 узлов не находятся на нижнем уровне кучи? Мы можем показать, что это не больше, чем 2 k-2 в силу противоречия. Предположим, что на нижнем уровне кучи имеется не менее 2 k-2 + 1 из самых больших узлов. Тогда каждый из родителей этих узлов также должен быть большими узлами на уровне k - 2. Даже в лучшем случае это означает, что на уровне k должно быть не менее 2 k-3 + 1 больших узлов. - 2, что означает, что на уровне k - 3 будет по крайней мере 2 k-4 + 1 больших узлов и т. Д. Суммируя по всем этим узлам, мы получаем, что существует 2 k-2 + 2 k-3 + 2 k-4 + ... + 2 0 + k больших узлов. Но это значение строго больше, чем 2 k-1 , что противоречит тому факту, что мы работаем только с 2 k-1 узлами.

Хорошо ... теперь мы знаем, что в нижнем слое есть не более 2 k-2 больших узлов. Это означает, что в первых слоях k-2 должно быть не менее 2 k-2 больших узлов. Теперь мы спросим - какова сумма расстояний от этого узла до корня по всем этим узлам? Итак, если у нас есть 2 k-2 узлов, расположенных где-то в полной куче, то самое большее 2 k-3 из них может быть на первых k - 3 уровнях На уровне k - 2 должно быть не менее 2 k-2 - 2 k-3 = 2 k-3 тяжелых узлов. Следовательно, общее количество Свопы, которые необходимо выполнить, составляют не менее (k - 2) 2 k-3 . Поскольку n = 2 k -1, k = & Theta; (lg n), и поэтому это значение равно & Theta; (n lg n), как требуется.

3 голосов
/ 04 января 2011

Простой ответ наблюдения таков: предметы в куче:

1
2
4
8
...
2^[log(n/4)]
and last level has between (1..2^[log(n/2)]) ==> (1,[n/2]) item, (by [] I mean Ceiling not roof)

, например, если у вас есть 7 предметов:

1
2
4

и если у вас есть 8 предметов:

1
2
4
1

Существует 2 разных дерева кучи, сначала не менее n / 4 - 1 предметов кучи находятся на последнем уровне, или нет, так что на уровне перед последним есть как минимум элемент n/4 - 1в первом случае требуется O((n/4 - 1) * log(n/2)) для удаления элементов последнего уровня из кучи, а во втором случае требуется O((n/4 - 1) * log(n/4)) для удаления элементов с предыдущего уровня.поэтому в обоих случаях требуется Ω (n log (n)) только для n / 4 - 1 элементов, так что это нижняя граница (легко сказать, что она жесткая, нижняя граница).

1 голос
/ 08 февраля 2012

Вот решение, которое использует термины CLRS:
Мы начнем с max-heap, представляющего собой полное двоичное дерево с n элементами.
Мы можем сказать, что в полном двоичном файле есть n/2листья и n/2 внутренние узлы.
n/2 итерации HEAP-SORT удаляют самые большие n/2 элементы из кучи.
Пусть S будет набором самых больших n/2 элементов.
В листьях может быть не более n/4 элементов из S, поскольку во внутренних узлах должно быть дополнительно n/4 из них.
Пусть L будут n/4 самыми большими элементами из Sкоторые находятся в листьях.
Так что если на уровне 0 (уровне листьев) есть n/4 элементов из S, то на уровне 1 их должно быть не менее n/8.
Let P эти n/8 элементы из S, которые находятся на уровне 1.
n/2 итерации HEAP-SORT могут дать элементам из L короткий путь к корню и затем из кучи, ноэлементы из P должны пройти до корня, прежде чем они будутoved from the heap.
Таким образом, есть по крайней мере (n/8)(lgn-1) операций, что дает нам время выполнения Ω (nlgn).
Теперь для случая max-heap, которая не имеет всех своих листьевна уровне 0.
Пусть k будет числом его листьев на уровне 0.
После k итераций HEAP-SORT у нас останется max-heap, представляющее собой полное двоичное дерево с высотойlgn-1.
Мы можем продолжить наше доказательство таким же образом.
Теперь для случая, когда есть меньше чем n/4 листьев из S.
Пусть k будет количеством элементов изS, которые находятся в листьях на уровне 0.
Если k <= n/8, то должно быть не менее n/8 элементов от S на уровне 1.
Это потому, что может быть всего n/4 элементы выше уровня 1.
Мы продолжаем доказательство таким же образом.
Если k>n/8, то должно быть не менее n/16 элементов из S, которые находятся на уровне 1.
Мы продолжаемдоказательство аналогично.
Мы заключаем, что время работы HEAP-SORT равно Ω (nlgn).

...