<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=94.25.229.122&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=94.25.229.122&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/94.25.229.122"/>
		<updated>2026-04-23T09:25:16Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%91%D0%B8%D0%BD%D0%BE%D0%BC%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%BA%D1%83%D1%87%D0%B0&amp;diff=31470</id>
		<title>Биномиальная куча</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%91%D0%B8%D0%BD%D0%BE%D0%BC%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%BA%D1%83%D1%87%D0%B0&amp;diff=31470"/>
				<updated>2013-06-09T20:48:00Z</updated>
		
		<summary type="html">&lt;p&gt;94.25.229.122: уменЬшение во(х-&amp;gt;з)можного&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Файл:binHeapExample.png|thumb|325px|Пример биномиальных деревьев &amp;lt;tex&amp;gt;B_0, B_2, B_3&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
= Биномиальное дерево =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt;''' {{---}} [[Дерево, эквивалентные определения|дерево]], определяемое для каждого &amp;lt;tex&amp;gt;k = 0, 1, 2, \dots &amp;lt;/tex&amp;gt; следующим образом: &amp;lt;tex&amp;gt;B_0&amp;lt;/tex&amp;gt; {{---}} дерево, состоящее из одного узла; &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; состоит из двух биномиальных деревьев &amp;lt;tex&amp;gt;B_{k-1}&amp;lt;/tex&amp;gt;, связанны вместе таким образом, что корень одного из них является дочерним узлом корня второго дерева.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства биномиальных деревьев ==&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;2^k&amp;lt;/tex&amp;gt; узлов&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем по индукции:&lt;br /&gt;
&lt;br /&gt;
База &amp;lt;tex&amp;gt;k = 1&amp;lt;/tex&amp;gt; {{---}} верно. Пусть для некоторого &amp;lt;tex&amp;gt;k &amp;lt;/tex&amp;gt; условие верно, то докажем, что для &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; это также верно:&lt;br /&gt;
&lt;br /&gt;
Так как в дереве порядка &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt; вдвое больше узлов, чем в дереве порядка &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, то дерево порядка &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt; имеет &amp;lt;tex&amp;gt;2^k \cdot 2 = 2^{k+1}&amp;lt;/tex&amp;gt; узлов. Переход доказан, то биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;2^k&amp;lt;/tex&amp;gt; узлов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет высоту &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;;&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем по индукции:&lt;br /&gt;
&lt;br /&gt;
База &amp;lt;tex&amp;gt;k = 1&amp;lt;/tex&amp;gt; {{---}} верно. Пусть для некоторого &amp;lt;tex&amp;gt;k &amp;lt;/tex&amp;gt; условие верно, то докажем, что для &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; это также верно:&lt;br /&gt;
&lt;br /&gt;
Так как в дереве порядка &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt; высота больше на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (так как мы подвешиваем к текущему дереву дерево того же порядка), чем в дереве порядка &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, то дерево порядка &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt; имеет высоту &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;. Переход доказан, то биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет высоту &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет ровно &amp;lt;tex&amp;gt;{k\choose i}&amp;lt;/tex&amp;gt; узлов на высоте &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;;&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем по индукции:&lt;br /&gt;
&lt;br /&gt;
База &amp;lt;tex&amp;gt;k = 1&amp;lt;/tex&amp;gt; {{---}} верно. Пусть для некоторого &amp;lt;tex&amp;gt;k &amp;lt;/tex&amp;gt; условие верно, то докажем, что для &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; это также верно:&lt;br /&gt;
&lt;br /&gt;
Рассмотрим &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; уровень дерева &amp;lt;tex&amp;gt;B_{k+1}&amp;lt;/tex&amp;gt;. Дерево &amp;lt;tex&amp;gt;B_{k+1}&amp;lt;/tex&amp;gt; было получено подвешиванием одного дерева порядка &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; к другому. Тогда на &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; уровне дерева &amp;lt;tex&amp;gt;B_{k+1}&amp;lt;/tex&amp;gt; всего узлов &amp;lt;tex&amp;gt;{k\choose i} + {k\choose {i - 1}}&amp;lt;/tex&amp;gt;, так как от подвешенного дерева в дерево порядка &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt; нам пришли узлы глубины &amp;lt;tex&amp;gt;i-1&amp;lt;/tex&amp;gt;. То для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го уровня дерева &amp;lt;tex&amp;gt;B_{k+1}&amp;lt;/tex&amp;gt; количество узлов &amp;lt;tex&amp;gt;{k\choose i} + {k\choose {i - 1}} ={{k + 1}\choose i} &amp;lt;/tex&amp;gt;. Переход доказан, то биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет ровно &amp;lt;tex&amp;gt;{k\choose i}&amp;lt;/tex&amp;gt; узлов на высоте &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Биномиальное дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет корень степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;; степень всех остальных вершин меньше степени корня биномиального дерева;&lt;br /&gt;
|proof=Так как в дереве порядка &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt; степень корня больше на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, чем в дереве порядка &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, а в дереве нулевого порядка степень корня &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, то дерево порядка &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; имеет корень степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. И так как при таком увеличении порядка (при переходе от дерева порядка &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;  к &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;) в полученном дереве лишь степень корня возрастает, то доказываемый инвариант, то есть степень корня больше степени остальных вершин, не будет нарушаться.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=В биномиальном дереве &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами максимальная степень произвольного узла равна &amp;lt;tex&amp;gt;\log(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем это утверждение для корня. Степень остальных вершин меньше по предыдущему свойству. Так как степень корня дерева порядка &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; равна &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, а узлов в этом дереве &amp;lt;tex&amp;gt;n = 2^k&amp;lt;/tex&amp;gt;, то прологарифмировав обе части получаем, что &amp;lt;tex&amp;gt;k=O(\log(n))&amp;lt;/tex&amp;gt;, то степень произвольного узла не более &amp;lt;tex&amp;gt;\log(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Биномиальная куча=&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Биномиальная куча  ''' представляет собой множество биномиальных деревьев, которые удовлетворяют следующим свойствам:&lt;br /&gt;
*Каждое биномиальное дерево в куче подчиняется свойству '''[[Двоичная куча|неубывающей кучи]]''': ключ узла не меньше ключа его родительского узла (упорядоченное в соответствии со свойством неубывающей кучи дерево).&lt;br /&gt;
*Для любого неотрицательного целого &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; найдется не более одного биномиального дерева, чей корень имеет степень &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
== Представление биномиальных куч ==&lt;br /&gt;
Поскольку количество детей у узлов варьируется в широких пределах, ссылка на детей осуществляется через левого ребенка, а остальные дети образуют односвязный список. Каждый узел в биномиальной куче представляется набором полей:&lt;br /&gt;
*&amp;lt;tex&amp;gt;key&amp;lt;/tex&amp;gt; {{---}} ключ (вес) элемента;&lt;br /&gt;
*&amp;lt;tex&amp;gt;parent&amp;lt;/tex&amp;gt; {{---}} указатель на родителя узла;&lt;br /&gt;
*&amp;lt;tex&amp;gt;child&amp;lt;/tex&amp;gt; {{---}} указатель на левого ребенка узла;&lt;br /&gt;
*&amp;lt;tex&amp;gt;sibling&amp;lt;/tex&amp;gt; {{---}} указатель на правого брата узла;&lt;br /&gt;
*&amp;lt;tex&amp;gt;degree&amp;lt;/tex&amp;gt; {{---}} степень узла (количество дочерних узлов данного узла).&lt;br /&gt;
&lt;br /&gt;
Корни деревьев, их которых состоит куча, содержатся в так называемом '''списке корней''', при проходе по которому степени соответствующих корней находятся в возрастающем порядке.&lt;br /&gt;
Доступ к куче осуществляется ссылкой на первый корень в списке корней.&lt;br /&gt;
&lt;br /&gt;
== Операции над биномиальными кучами==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операции, которые можно производить с биномиальной кучей. Время работы указано в таблице:&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
 |insert&lt;br /&gt;
 |&amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |getMinimum&lt;br /&gt;
 |&amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |extractMin&lt;br /&gt;
 |&amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |merge&lt;br /&gt;
 |&amp;lt;tex&amp;gt;\Omega(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |decreaseKey&lt;br /&gt;
 |&amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |delete&lt;br /&gt;
 |&amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
Обозначим нашу кучу за &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;. То пусть &amp;lt;tex&amp;gt;H.head&amp;lt;/tex&amp;gt; {{---}} указатель на корень биномиального дерева минимального порядка этой кучи. Изначально &amp;lt;tex&amp;gt;H.head = null&amp;lt;/tex&amp;gt;, то есть куча не содержит элементов.&lt;br /&gt;
&lt;br /&gt;
=== getMinimum ===&lt;br /&gt;
Для нахождения минимального элемента надо найти элемент в списке корней с минимальным значением (предполагается, что ключей, равных &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt;, нет).&lt;br /&gt;
&lt;br /&gt;
Так как корней в этом списке не более &amp;lt;tex&amp;gt;\lfloor \log(n) \rfloor + 1&amp;lt;/tex&amp;gt;, то операция выполняется за &amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При вызове этой процедуры для кучи, изображенной на картинке ниже, будет возвращен указатель на вершину с ключом &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:binHeapExample1_1.png|370px]]&lt;br /&gt;
&lt;br /&gt;
=== merge ===&lt;br /&gt;
Эта операция, соединяющая две биномиальные кучи в одну, используется в качестве подпрограммы большинством остальных операций.&lt;br /&gt;
&lt;br /&gt;
Вот в чем состоит ее суть: пусть есть две биномиальные кучи с &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H'&amp;lt;/tex&amp;gt;. Размеры деревьев в кучах соответствуют двоичным числам &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, то есть при наличии дерева соответствующего порядка в этом разряде числа стоит единица, иначе ноль. При сложении столбиком в двоичной системе происходят переносы, которые соответствуют слияниям двух биномиальных деревьев &amp;lt;tex&amp;gt;B_{k-1}&amp;lt;/tex&amp;gt; в дерево     &amp;lt;tex&amp;gt;B_{k}&amp;lt;/tex&amp;gt;. Надо только посмотреть, в каком из сливаемых деревьев корень меньше, и считать его верхним (пример работы для одного случая приведен на рисунке справа; в другом случае подвешиваем наоборот).&lt;br /&gt;
&lt;br /&gt;
[[Файл:helpBinaryHeapBoris.png|Пример слияние двух деревьев одного порядка]]&lt;br /&gt;
&lt;br /&gt;
Работа этой процедуры начинается с соединения корневых списков куч в единый список, в котором корневые вершины идут в порядке неубывания их степеней.&lt;br /&gt;
&lt;br /&gt;
В получившемся списке могут встречаться пары соседних вершин одинаковой степени. Поэтому мы начинаем соединять деревья равной степени и делаем это до тех пор, пока деревьев одинаковой степени не останется. Этот процесс соответствует сложению двоичных чисел столбиком, и время его работы пропорционально числу корневых вершин, то есть операция выполняется за &amp;lt;tex&amp;gt;\Omega(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 Node merge(H1, H2)&lt;br /&gt;
    if H1 == null &lt;br /&gt;
       return H2 &lt;br /&gt;
     &lt;br /&gt;
    if H2 == null &lt;br /&gt;
       return H1 &lt;br /&gt;
   &lt;br /&gt;
    // H - результат слияния&lt;br /&gt;
    H.head = null&lt;br /&gt;
 &lt;br /&gt;
    // Слияние корневых списков&lt;br /&gt;
    curH = H.head&lt;br /&gt;
    curH1 = H1.head&lt;br /&gt;
    curH2 = H2.head&lt;br /&gt;
    while curH1 != null &amp;amp;&amp;amp; curH2 != null &lt;br /&gt;
       if curH1.degree &amp;lt; curH2.degree &lt;br /&gt;
          curH.sibling = curH1&lt;br /&gt;
          curH = curH1&lt;br /&gt;
          curH1 = curH1.sibling&lt;br /&gt;
       else &lt;br /&gt;
          curH.sibling = curH2&lt;br /&gt;
          curH = curH2&lt;br /&gt;
          curH2 = curH2.sibling&lt;br /&gt;
 &lt;br /&gt;
    if curH1 == null &lt;br /&gt;
       while curH2 != null &lt;br /&gt;
          curH.sibling = curH2&lt;br /&gt;
          curH2 = curH2.sibling&lt;br /&gt;
    else &lt;br /&gt;
       while curH1 != null &lt;br /&gt;
          curH.sibling = curH1&lt;br /&gt;
          curH1 = curH1.sibling&lt;br /&gt;
      &lt;br /&gt;
    // объединение деревьев одной степени&lt;br /&gt;
    curH = H.head&lt;br /&gt;
    while curH.sibling != null &lt;br /&gt;
       if curH.degree == curH.sibling.degree&lt;br /&gt;
          p[curH] = curH.sibling&lt;br /&gt;
          tmp = curH.sibling&lt;br /&gt;
          curH.sibling = curH.sibling.child&lt;br /&gt;
          curH = tmp&lt;br /&gt;
          continue&lt;br /&gt;
      &lt;br /&gt;
       curH = curH.sibling&lt;br /&gt;
 &lt;br /&gt;
    return H&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== insert ===&lt;br /&gt;
Чтобы добавить новый элемент в биномиальную кучу нужно создать биномиальную кучу &amp;lt;tex&amp;gt;H'&amp;lt;/tex&amp;gt; с единственным узлом, содержащим этот элемент, за время &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; и объединить ее с биномиальной кучей &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;, так как в данном случае куча &amp;lt;tex&amp;gt;H'&amp;lt;/tex&amp;gt; содержит лишь одно дерево.&lt;br /&gt;
&lt;br /&gt;
=== extractMin ===&lt;br /&gt;
&lt;br /&gt;
Приведенная ниже процедура извлекает узел с минимальным ключом из биномиальной кучи и возвращает указатель на извлеченный узел. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим пошагово алгоритм:&lt;br /&gt;
* Найдем биномиальное дерево с минимальным корневым значением. Предположим, что это дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt;. Время работы этого шага алгоритма &amp;lt;tex&amp;gt;\Theta(\log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Удаляем дерево &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt; из кучи &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;. Иными словами удаляем его корень из списка корней кучи. Это можно сделать за время &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;H'&amp;lt;/tex&amp;gt; {{---}} куча детей найденного корня. При этом мы для каждого из ребенка устанавливаем указатель на предка равным &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;. После этого сливаем кучу &amp;lt;tex&amp;gt;H'&amp;lt;/tex&amp;gt; c &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;\Omega(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Процедура выполняется за время &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;, поскольку всего в списке &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt; корней биномиальных деревьев. И всего у найденного дерева &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; порядка (с минимальным значением ключа) ровно &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; детей, то сложность перебора этих детей будет тоже &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;. А процесс слияния выполняется за &amp;lt;tex&amp;gt;\Omega(\log(n))&amp;lt;/tex&amp;gt;. Таким образом операция выполняется &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:BinHeapExampleNew31.png|700px|Примеp извлечения минимума]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  Node extractMin(H) &lt;br /&gt;
    //поиск корня х с минимальным значением ключа в списке корней Н:&lt;br /&gt;
    min = &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt;&lt;br /&gt;
    x = null&lt;br /&gt;
    xBefore = null&lt;br /&gt;
 &lt;br /&gt;
    curx = H.head&lt;br /&gt;
    curxBefore = null&lt;br /&gt;
    while curx != null &lt;br /&gt;
       // релаксируем текущий минимум&lt;br /&gt;
       if curx.key &amp;lt; min &lt;br /&gt;
          min = curx.key&lt;br /&gt;
          x = curx &lt;br /&gt;
          xBefore = curxBefore &lt;br /&gt;
      &lt;br /&gt;
       curxBefore = curx&lt;br /&gt;
       curx = curx.sibling&lt;br /&gt;
    &lt;br /&gt;
    //удаление найденного корня x из списка корней деревьев кучи&lt;br /&gt;
    if (xBefore == null) &lt;br /&gt;
       H.head = x.sibling&lt;br /&gt;
    else &lt;br /&gt;
       xBefore.sibling = x.sibling&lt;br /&gt;
    &lt;br /&gt;
 &lt;br /&gt;
    //построение кучи детей вершины x, при этом изменяем предка соответствующего ребенка на null:&lt;br /&gt;
    H' = null&lt;br /&gt;
    curx = x.child&lt;br /&gt;
    H'.head = x.child&lt;br /&gt;
    while curx != null &lt;br /&gt;
       // меняем указатель на родителя узла curx&lt;br /&gt;
       p[curx] = null&lt;br /&gt;
       // переход к следующему ребенку&lt;br /&gt;
       curx = curx.sibling&lt;br /&gt;
   &lt;br /&gt;
    // слияние нашего дерева с деревом H'&lt;br /&gt;
    H = merge(H, H') &lt;br /&gt;
    return x&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== decreaseKey ===&lt;br /&gt;
Следующая процедура уменьшает ключ элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; биномиальной кучи, присваивая ему новое значение. Вершина, ключ которой был уменьшен, «всплывает» как в обычной куче. Процедура выполняется за время &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;, поскольку глубина вершины &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; в худшем случае есть &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt; (свойства биномиального дерева), а при выполнении каждого шага алгоритма мы поднимаемся вверх.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  void decreaseKey(H, x, k)  &lt;br /&gt;
   // проверка на то, что текущий ключ не меньше передаваемого ключа k&lt;br /&gt;
    if k &amp;gt; key[x]&lt;br /&gt;
       return&lt;br /&gt;
    key[x] = k&lt;br /&gt;
    y = x&lt;br /&gt;
    z = p[y]&lt;br /&gt;
    //поднимаем текущий элемент x с новым ключом k, пока&lt;br /&gt;
    //это значение меньше значения в родительской вершине &lt;br /&gt;
    while z != null and key[y] &amp;lt; key[z]&lt;br /&gt;
       swap(key[y], key[z])&lt;br /&gt;
       y = z&lt;br /&gt;
       z = p[y]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример работы процедуры проиллюстрирован на рисунке (&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; {{---}} уменьшаемый элемент, &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} его предок).&lt;br /&gt;
&lt;br /&gt;
[[Файл:binHeapExample3_2.png|370px]]&lt;br /&gt;
&lt;br /&gt;
=== delete ===&lt;br /&gt;
Удаление ключа сводится к операциям decreaseKey и extractMin: сначала нужно уменьшить ключ до минимально возможного значения, а затем извлечь вершину с минимальным ключом. В процессе выполнения процедуры этот узел всплывает вверх, откуда и удаляется. Процедура выполняется за время &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;, поскольку каждая из операций, которые используется в реализации, работают за &amp;lt;tex&amp;gt;\Theta(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  void delete(H, x) &lt;br /&gt;
    //уменьшение ключа до минимально возможного значения&lt;br /&gt;
    decreaseKey(H, x, &amp;lt;tex&amp;gt;-\infty&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    //удаление &amp;quot;всплывшего&amp;quot; элемента&lt;br /&gt;
    extractMin(H)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/dscm/7/ Биномиальные кучи  — INTUIT.ru]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Binomial_heap Binomial heap — Wikipedia]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 538—558. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Приоритетные очереди]]&lt;/div&gt;</summary>
		<author><name>94.25.229.122</name></author>	</entry>

	</feed>