mirror of
https://github.com/krahets/hello-algo.git
synced 2026-09-23 06:46:34 +08:00
deploy
This commit is contained in:
@@ -4383,11 +4383,11 @@
|
||||
<h2 id="821">8.2.1 Реализация через операцию добавления в кучу<a class="headerlink" href="#821" title="Permanent link">¶</a></h2>
|
||||
<p>Сначала мы создаем пустую кучу, затем обходим список и для каждого элемента по очереди выполняем операцию добавления в кучу: сначала помещаем элемент в хвост кучи, а затем выполняем для него упорядочивание снизу вверх.</p>
|
||||
<p>Каждый раз, когда элемент добавляется в кучу, ее длина увеличивается на единицу. Поскольку узлы последовательно добавляются в двоичное дерево сверху вниз, куча строится сверху вниз.</p>
|
||||
<p>Пусть число элементов равно <span class="arithmatex">\(n\)</span> ; так как каждая операция добавления требует <span class="arithmatex">\(O(\log{n})\)</span> времени, временная сложность такого построения кучи составляет <span class="arithmatex">\(O(n \log n)\)</span> .</p>
|
||||
<p>Пусть число элементов равно <span class="arithmatex">\(n\)</span>. Так как каждая операция добавления требует <span class="arithmatex">\(O(\log{n})\)</span> времени, временная сложность такого построения кучи составляет <span class="arithmatex">\(O(n \log n)\)</span> .</p>
|
||||
<h2 id="822">8.2.2 Реализация через обход и упорядочивание<a class="headerlink" href="#822" title="Permanent link">¶</a></h2>
|
||||
<p>На самом деле можно реализовать и более эффективный способ построения кучи, который состоит из двух шагов.</p>
|
||||
<ol>
|
||||
<li>Без изменений добавить все элементы списка в кучу; в этот момент свойства кучи еще не выполняются.</li>
|
||||
<li>Без изменений добавить все элементы списка в кучу. В этот момент свойства кучи еще не выполняются.</li>
|
||||
<li>Обойти кучу в обратном порядке, то есть в порядке, обратном обходу по уровням, и по очереди выполнить упорядочивание сверху вниз для каждого нелистового узла.</li>
|
||||
</ol>
|
||||
<p><strong>После того как некоторый узел был упорядочен, поддерево с этим узлом в качестве корня становится корректной подкучей</strong>. А поскольку обход выполняется в обратном порядке, куча строится снизу вверх.</p>
|
||||
@@ -4678,11 +4678,11 @@
|
||||
<li>В процессе упорядочивания сверху вниз каждый узел в худшем случае может просеяться до листа, поэтому максимальное число итераций равно высоте двоичного дерева <span class="arithmatex">\(\log n\)</span> .</li>
|
||||
</ul>
|
||||
<p>Перемножив эти два значения, можно получить временную сложность построения кучи <span class="arithmatex">\(O(n \log n)\)</span> . <strong>Но эта оценка неточна, потому что мы не учли свойство двоичного дерева: на нижних уровнях узлов гораздо больше, чем на верхних</strong>.</p>
|
||||
<p>Далее выполним более точный расчет. Чтобы упростить вычисления, предположим, что дано "идеальное двоичное дерево" высоты <span class="arithmatex">\(h\)</span> с числом узлов <span class="arithmatex">\(n\)</span> ; это предположение не повлияет на корректность результата.</p>
|
||||
<p>Далее выполним более точный расчет. Чтобы упростить вычисления, предположим, что дано «идеальное двоичное дерево» высоты <span class="arithmatex">\(h\)</span> с числом узлов <span class="arithmatex">\(n\)</span>. Это предположение не повлияет на корректность результата.</p>
|
||||
<p><img alt="Число узлов на каждом уровне идеального двоичного дерева" class="animation-figure" src="../build_heap.assets/heapify_operations_count.png" /></p>
|
||||
<p align="center"> Рисунок 8-5 Число узлов на каждом уровне идеального двоичного дерева </p>
|
||||
|
||||
<p>Как показано на рисунке 8-5, максимальное число итераций упорядочивания сверху вниз для некоторого узла равно расстоянию от этого узла до листового узла, а это расстояние как раз и есть высота узла. Поэтому мы можем просуммировать для каждого уровня выражение "число узлов <span class="arithmatex">\(\times\)</span> высота узла" и <strong>получить суммарное число итераций упорядочивания для всех узлов</strong>.</p>
|
||||
<p>Как показано на рисунке 8-5, максимальное число итераций упорядочивания сверху вниз для некоторого узла равно расстоянию от этого узла до листового узла, а это расстояние как раз и есть высота узла. Поэтому мы можем просуммировать для каждого уровня выражение «число узлов <span class="arithmatex">\(\times\)</span> высота узла» и <strong>получить суммарное число итераций упорядочивания для всех узлов</strong>.</p>
|
||||
<div class="arithmatex">\[
|
||||
T(h) = 2^0h + 2^1(h-1) + 2^2(h-2) + \dots + 2^{(h-1)}\times1
|
||||
\]</div>
|
||||
|
||||
Reference in New Issue
Block a user