Изменения

Перейти к: навигация, поиск

Левосторонняя куча

159 байт убрано, 19:05, 4 сентября 2022
м
rollbackEdits.php mass rollback
'''if''' dist(x.right) > dist(x.left):
swap(x.left, x.right)
dist(x) = min(dist(x.left), dist(x.right)) + 1 <font color=darkgreen>// пересчитаем расстояние до ближайшей свободной позиции</font>
'''return''' x
<font color=darkgreen>// Каждый раз идем из уже существующей вершины только в правое поддерево {{---}} не более логарифма вызовов (по лемме)</font>
|id=lemma2
|about=2
|statement=У левостороннего дерева с правой ветвью длинны длины <tex>h</tex> количество узлов <tex>n \geqslant 2^{h} - 1</tex>.
|proof=Индукция по h.
Пусть на <tex> i </tex>-ом шаге алгоритма в нашем списке остались только кучи размера <tex> 2^i </tex>. На нулевом шаге у нас <tex> n </tex> куч из одного элемента, и на каждом следующем количество куч будет уменьшаться вдвое, а число вершин в куче будет увеличиваться вдвое. Слияние двух куч из <tex> n_i </tex> элементов выполняется за <tex> O(\log{n_i}) </tex>. Поэтому построение будет выполняться за
<tex dpi = 130> \sum\limits_{i = 1}^{\left\lceil \log{n} \right\rceil} \genfrac{}{}{}{0}dfrac{n \cdot \log{n_i}}{2^i} = n \cdot \sum\limits_{i = 1}^{\left\lceil \log{n} \right\rceil} \genfrac{}{}{}{0}dfrac{\log{2^i}}{2^i} = n \cdot \sum\limits_{i = 1}^{\left\lceil \log{n} \right\rceil} \genfrac{}{}{}{0}dfrac{i}{2^i}
</tex>
Покажем, что сумма {{---}} <tex> O(1) </tex>, тогда и алгоритм будет выполняться за <tex> O(n) </tex>. Найдём сумму [[Определение суммы числового ряда|ряда]], заменив его на эквивалентный [[Определение функционального ряда|функциональный]]:
<tex dpi = 130> \sum\limits_{i = 1}^{\left\lceil \log{n} \right\rceil} \genfrac{}{}{}{0}dfrac{i}{2^i} < \sum\limits_{i = 1}^{\infty } \genfrac{}{}{}{0}dfrac{i}{2^i} \\
f(x) = \sum\limits_{i = 1}^{\infty } \Bigl. i \cdot x^i \Bigr|_{x = \frac{1}{2}} \\
~\genfrac{}{}{}{0}dfrac{f(x)}{x} = \sum\limits_{i = 1}^{\infty } i \cdot x^{i - 1} = \sum\limits_{i = 1}^{\infty } (x^i)' = \left(\sum\limits_{i = 1}^{\infty } x^i\right)' \\~\int\genfrac{}{}{}{0}dfrac{f(x)}{x} = \sum\limits_{i = 1}^{\infty } x^i =~\genfrac{}{}{}{0}dfrac{1}{1 - x} - 1 \\~\genfrac{}{}{}{0}dfrac{f(x)}{x} = \left(\genfrac{}{}{}{0}dfrac{1}{1 - x} - 1\right)' = \genfrac{}{}{}{0}dfrac{1}{(1 - x)^2} \\~f(x) = \genfrac{}{}{}{0}dfrac{x}{(1 - x)^2}
</tex>
После подстановки <tex> x = \genfrac{}{}{}{0}dfrac{1}{2} </tex> получаем, что сумма равна <tex> 2 </tex>. Следовательно, построение кучи таким образом произойдёт за <tex> O(n) </tex>. 
==Преимущества левосторонней кучи==
Нигде не делается уничтожающих присваиваний. Не создается новых узлов в <tex>\mathrm{merge}</tex>. Эта реализация слияния является функциональной — ее легко реализовать на функциональном языке программирования. Также данная реализация <tex>\mathrm{merge}</tex> является персистентной.
1632
правки

Навигация