<?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=176.195.102.171&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=176.195.102.171&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/176.195.102.171"/>
		<updated>2026-05-07T23:13:05Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%BE%D0%BD%D0%BA%D0%B0%D1%8F_%D0%BA%D1%83%D1%87%D0%B0&amp;diff=65261</id>
		<title>Тонкая куча</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%BE%D0%BD%D0%BA%D0%B0%D1%8F_%D0%BA%D1%83%D1%87%D0%B0&amp;diff=65261"/>
				<updated>2018-05-07T05:01:56Z</updated>
		
		<summary type="html">&lt;p&gt;176.195.102.171: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Тонкая куча''' (англ. ''Thin heap'') {{---}} структура данных, реализующая приоритетную очередь с теми же асимптотическими оценками, что и [[Фибоначчиева куча|фибоначчиева куча]], но имеющая большую практическую ценность из-за меньших констант.&lt;br /&gt;
&lt;br /&gt;
Тонкие кучи, как и многие другие [[Двоичная куча|кучеобразные]] структуры, аналогичны [[Биномиальная куча|биномиальным кучам]].&lt;br /&gt;
= Тонкое дерево =&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=thin_tree_def&lt;br /&gt;
|definition='''Тонкое дерево''' (англ. ''Thin tree'') &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt; ранга &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} это дерево, которое может быть получено из [[Биномиальная куча#Биномиальное дерево|биномиального дерева]] &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;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;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;
|id=about_thin_tree_rank&lt;br /&gt;
|statement=Ранг тонкого дерева равен количеству детей его корня.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Для любого узла &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; в дереве &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt; обозначим:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{Degree(x)}&amp;lt;/tex&amp;gt; {{---}} количество детей узла &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{Rank(x)}&amp;lt;/tex&amp;gt; {{---}} ранг соответствующего узла в [[Биномиальная куча#Биномиальное дерево|биномиальном дереве]] &amp;lt;tex&amp;gt;B_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства тонкого дерева ==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=about_thin_tree&lt;br /&gt;
|statement=Тонкое дерево обладает следующими свойствами:&lt;br /&gt;
# Для любого узла &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; либо &amp;lt;tex&amp;gt;\mathtt{Degree(x)=Rank(x)}&amp;lt;/tex&amp;gt;, в этом случае говорим, что узел &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не тонкий (полон); либо &amp;lt;tex&amp;gt;\mathtt{Degree(x)=Rank(x)-1}&amp;lt;/tex&amp;gt;, в этом случае говорим, что узел &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тонкий (не полон).&lt;br /&gt;
# Корень не тонкий (полон).&lt;br /&gt;
# Для любого узла &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; ранги его детей от самого правого к самому левому равны соответственно &amp;lt;tex&amp;gt;\mathtt{0,1,2,...,Degree(x)-1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Узел &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тонкий тогда и только тогда, когда его ранг на 2 больше, чем ранг его самого левого сына, или его ранг равен 1, и он не имеет детей.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Файл:Thin_trees.png|200x200px|слева|frame|Из [[Биномиальная куча#Биномиальное дерево|биномиального дерева]] ранга 3 получены два тонких дерева. Числа обозначают ранги узлов, закрашенные вершины являются тонкими (не имеют самого левого сына)]]&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Тонкая куча ==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=thin_forest_def&lt;br /&gt;
|definition='''Тонкий лес''' (англ. ''Thin forest'') {{---}} это набор тонких деревьев, ранги которых не обязательно попарно различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=about_thin_forest_with_n_nodes&lt;br /&gt;
|statement=Для любого натурального числа &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; существует тонкий лес, который содержит ровно &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементов и состоит из тонких деревьев попарно различных рангов.&lt;br /&gt;
|proof=Действительно, любой [[Биномиальная куча#Биномиальное дерево|биномиальный лес]] является тонким, а для биномиального леса рассматриваемое утверждение справедливо.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=thin_heap_def&lt;br /&gt;
|definition='''Тонкая куча''' (англ. ''Thin heap'') {{---}} это [[Двоичная куча|кучеобразно]] нагруженный тонкий лес, то есть каждое тонкое дерево удовлетворяет условиям [[Двоичная куча|кучи]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;D(n)&amp;lt;/tex&amp;gt; {{---}} максимально возможный ранг узла в тонкой куче, содержащей &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементов.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=max_rank_th&lt;br /&gt;
|about=О максимальном ранге узла&lt;br /&gt;
|statement=В тонкой куче из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементов &amp;lt;tex&amp;gt;D(n) \leqslant \log_{\Phi} n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\varphi=\dfrac{1+\sqrt{5}}{2}&amp;lt;/tex&amp;gt; {{---}} золотое сечение.&lt;br /&gt;
|proof=Сначала покажем, что узел ранга &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; в тонком дереве имеет не менее &amp;lt;tex&amp;gt;F_k \geqslant \varphi^{k-1}&amp;lt;/tex&amp;gt; потомков, включая самого себя, где &amp;lt;tex&amp;gt;F_k&amp;lt;/tex&amp;gt; — &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-е число Фибоначчи.&lt;br /&gt;
&lt;br /&gt;
Действительно, пусть &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt; {{---}} минимально возможное число узлов, включая самого себя, в тонком дереве ранга &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. По свойствам &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt; тонкого дерева получаем следующие соотношения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;T_0=1,T_1=1,T_k \geqslant 1+\sum\limits_{i=0}^{k-2}T_i&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;k \geqslant 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Числа Фибоначчи удовлетворяют этому же рекуррентному соотношению, причем неравенство можно заменить равенством. Отсюда по индукции следует, что &amp;lt;tex&amp;gt;T_k \geqslant F_k&amp;lt;/tex&amp;gt; для любых &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. Неравенство &amp;lt;tex&amp;gt;F_k \geqslant \varphi^{k-1}&amp;lt;/tex&amp;gt; [[Фибоначчиева куча#Лемма3|хорошо известно]].&lt;br /&gt;
&lt;br /&gt;
Теперь убедимся в том, что максимально возможный ранг &amp;lt;tex&amp;gt;D(n)&amp;lt;/tex&amp;gt; тонкого дерева в тонкой куче, содержащей &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементов, не превосходит числа &amp;lt;tex&amp;gt;\log_{\varphi}(n)+1&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Действительно, выберем в тонкой куче дерево максимального ранга. Пусть &amp;lt;tex&amp;gt;n^*&amp;lt;/tex&amp;gt; {{---}} количество вершин в этом дереве, тогда &amp;lt;tex&amp;gt;n \geqslant n^* \geqslant \varphi^{D(n)-1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Отсюда следует, что &amp;lt;tex&amp;gt;D(n)\leqslant\log_{\varphi}(n)+1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Структура ==&lt;br /&gt;
=== Структура узла ===&lt;br /&gt;
 '''struct''' Node&lt;br /&gt;
    '''int''' key &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;     // ключ&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''int''' rank &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;    // ранг узла&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' child &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // указатель на самого левого ребенка узла&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' right &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // указатель на правого брата узла, либо на следующий корень, если текущий узел корень&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' left &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;   // указатель на левого брата узла, либо на родителя, если текущий узел самый левый, либо null, если это корень&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для ускорения проверки на тонкость (англ. ''thinness'') можно отдельно хранить тонкость вершины.&lt;br /&gt;
Также в вершине можно хранить любую дополнительную информацию.&lt;br /&gt;
&lt;br /&gt;
=== Структура кучи ===&lt;br /&gt;
 '''struct''' ThinHeap&lt;br /&gt;
    '''Node''' first &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // указатель на корень дерева с минимальным ключом&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' last &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;   // указатель на последний корень&amp;lt;/span&amp;gt;&lt;br /&gt;
== Операции над тонкой кучей ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операции, которые можно производить над тонкой кучей. Время работы указано в таблице:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:10cm&amp;quot; border=1&lt;br /&gt;
|+&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#EEEEFF&lt;br /&gt;
! Операция || Время работы &lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
|&amp;lt;tex&amp;gt;\mathrm{makeHeap}&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
|&amp;lt;tex&amp;gt;\mathrm{insert}&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
||&amp;lt;tex&amp;gt;\mathrm{getMin}&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
|&amp;lt;tex&amp;gt;\mathrm{merge}&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
|&amp;lt;tex&amp;gt;\mathrm{extractMin}&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
|&amp;lt;tex&amp;gt;\mathrm{decreaseKey}&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
|&amp;lt;tex&amp;gt;\mathrm{delete}&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;O(\log(n))&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;
Пусть функция потенциала определена как &amp;lt;tex&amp;gt;\Phi = n + 2 \cdot m&amp;lt;/tex&amp;gt; где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} это количество тонких деревьев в куче, а &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} это количество тонких вершин.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=about_thin_heap_potential&lt;br /&gt;
|statement=Определённый таким образом потенциал обладает свойствами:&lt;br /&gt;
# &amp;lt;tex&amp;gt;\Phi \geqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для пустой тонкой кучи &amp;lt;tex&amp;gt;\Phi = 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
 &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathtt{Node}&amp;lt;/tex&amp;gt; {{---}} узел тонкого дерева, а &amp;lt;tex&amp;gt;\mathtt{ThinHeap}&amp;lt;/tex&amp;gt; {{---}} тонкая куча, причём &amp;lt;tex&amp;gt;\mathtt{ThinHeap}&amp;lt;/tex&amp;gt; содержит ссылки на первый и последний корень &amp;lt;tex&amp;gt;\mathtt{first}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathtt{last}&amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
&lt;br /&gt;
Также введем вспомогательную функцию проверки узла на тонкость, для этого воспользуемся тем, что у левого сына узла &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; ранг равен &amp;lt;tex&amp;gt;\mathtt{Degree(x) - 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''bool''' isThin(x: '''Node'''):&lt;br /&gt;
   '''if''' x.rank == 1&lt;br /&gt;
      '''return''' x.child == ''null''&lt;br /&gt;
   '''else'''&lt;br /&gt;
      '''return''' x.child.rank + 1 != x.rank&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== makeHeap ===&lt;br /&gt;
Для создания новой пустой тонкой кучи нужно вернуть ссылку на новый пустой корневой список, его потенциал &amp;lt;tex&amp;gt;\Phi=0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
 '''ThinHeap''' makeHeap():&lt;br /&gt;
    H.first = ''null''&lt;br /&gt;
    H.last = ''null''  &lt;br /&gt;
    '''return''' H&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Стоимость &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== insert ===&lt;br /&gt;
&lt;br /&gt;
Для вставки элемента в тонкую кучу нужно создать новое тонкое дерево из единственного узла &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; с ключом &amp;lt;tex&amp;gt;x.key&amp;lt;/tex&amp;gt;, добавить его в корневой список на первое место, если этот ключ минимален, либо на последнее. Потенциал &amp;lt;tex&amp;gt;\Phi&amp;lt;/tex&amp;gt; увеличивается на 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
 '''void''' insert(H: '''ThinHeap''', x: '''Node'''):&lt;br /&gt;
    '''if''' H.first == ''null''&lt;br /&gt;
       H.first = x&lt;br /&gt;
       H.last = x&lt;br /&gt;
    '''else'''&lt;br /&gt;
       '''if''' x.key &amp;lt; H.first.key&lt;br /&gt;
          x.right = H.first&lt;br /&gt;
          H.first = x&lt;br /&gt;
       '''else'''&lt;br /&gt;
          H.last.right = x&lt;br /&gt;
          H.last = x  &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Стоимость &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== getMin ===&lt;br /&gt;
&lt;br /&gt;
Для обращения к минимальному элементу в тонкой куче нужно обратиться к первому корневому узлу списка и вернуть его ключ, потенциал &amp;lt;tex&amp;gt;\Phi&amp;lt;/tex&amp;gt; не меняется. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''Node''' getMin(H: '''ThinHeap'''):&lt;br /&gt;
    '''return''' H.first&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Стоимость &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== merge ===&lt;br /&gt;
&lt;br /&gt;
Для объединения тонких куч нужно слить их корневые списки, ставя первым тот список, у которого ключ первого корня минимален. Суммарный потенциал &amp;lt;tex&amp;gt;\Phi&amp;lt;/tex&amp;gt; не меняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''ThinHeap''' merge(H1: '''ThinHeap''', H2: '''ThinHeap'''):&lt;br /&gt;
    '''if''' H1.first == ''null''&lt;br /&gt;
       '''return''' H2&lt;br /&gt;
    '''else'''&lt;br /&gt;
       '''if''' H2.first == ''null''&lt;br /&gt;
          '''return''' H1&lt;br /&gt;
       '''else''' &lt;br /&gt;
          '''if''' H1.first.key &amp;lt; H2.first.key&lt;br /&gt;
             H1.last.right = H2.first&lt;br /&gt;
             H1.last = H2.last&lt;br /&gt;
             '''return''' H1&lt;br /&gt;
          '''else'''&lt;br /&gt;
             H2.last.right = H1.first&lt;br /&gt;
             H2.last = H1.last&lt;br /&gt;
             '''return''' H2&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Стоимость &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== extractMin ===&lt;br /&gt;
Чтобы извлечь минимальный элемент из тонкой кучи нужно:&lt;br /&gt;
# Удалить корень с минимальным ключом из корневого списка.&lt;br /&gt;
# Уменьшить ранг для всех его тонких детей.&lt;br /&gt;
# Cлить детей с корневым списком.&lt;br /&gt;
# Объединять, пока возможно, тонкие деревья одного ранга.&lt;br /&gt;
&lt;br /&gt;
Это можно сделать, например, с помощью вспомогательного массива размером &amp;lt;tex&amp;gt;O(D(n))&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейке которого хранится корень тонкого дерева &amp;lt;tex&amp;gt;T_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;
При добавлении нового дерева мы, если дерево такого ранга уже есть в массиве, связываем его с существующим и пытаемся добавить новое дерево с рангом на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; больше.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''Node''' extractMin(H: '''ThinHeap'''):&lt;br /&gt;
    &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Удаляем минимальный корень из корневого списка&amp;lt;/span&amp;gt;&lt;br /&gt;
    tmp = H.first&lt;br /&gt;
    H.first = H.first.right&lt;br /&gt;
    '''if''' H.first == ''null''&lt;br /&gt;
       H.last = ''null''&lt;br /&gt;
    &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Снимаем тонкость с его детей и добавляем их в корневой список&amp;lt;/span&amp;gt;&lt;br /&gt;
    x = tmp.first.child&lt;br /&gt;
    '''while''' x != ''null''&lt;br /&gt;
       '''if''' isThin(x) &lt;br /&gt;
          x.rank = x.rank - 1&lt;br /&gt;
       x.left = ''null''&lt;br /&gt;
       next = x.right&lt;br /&gt;
       insert(H, x)&lt;br /&gt;
       x = next&lt;br /&gt;
    &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Объединяем все корни одного ранга с помощью вспомогательного массива aux&amp;lt;/span&amp;gt;&lt;br /&gt;
    max = -1&lt;br /&gt;
    x = H.first&lt;br /&gt;
    '''while''' x != ''null''&lt;br /&gt;
       '''while''' aux[x.rank] != ''null''&lt;br /&gt;
          next = x.right&lt;br /&gt;
          '''if''' aux[x.rank].key &amp;lt; x.key&lt;br /&gt;
             swap(aux[x.rank], x)&lt;br /&gt;
          aux[x.rank].right = x.child&lt;br /&gt;
          x.child.left = aux[x.rank]&lt;br /&gt;
          aux[x.rank].left = x&lt;br /&gt;
          x.child = aux[x.rank]&lt;br /&gt;
          aux[x.rank] = ''null''           &lt;br /&gt;
          x.rank = x.rank + 1&lt;br /&gt;
       aux[x.rank] = x&lt;br /&gt;
       '''if''' x.rank &amp;gt; max &lt;br /&gt;
          max = x.rank   &lt;br /&gt;
       x = next&lt;br /&gt;
    &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Собираем все корни обратно в тонкую кучу&amp;lt;/span&amp;gt;&lt;br /&gt;
    H = makeHeap()&lt;br /&gt;
    i = 0&lt;br /&gt;
    '''while''' i &amp;lt;= max&lt;br /&gt;
       insert(H, aux[i])&lt;br /&gt;
       i = i + 1&lt;br /&gt;
    '''return''' tmp&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть мы сделали &amp;lt;tex&amp;gt;ls&amp;lt;/tex&amp;gt; связывающих шагов (англ. ''linking steps'') во время добавления в массив.&lt;br /&gt;
&lt;br /&gt;
Мы удалили корень из списка за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, затем за &amp;lt;tex&amp;gt;O(D(n))&amp;lt;/tex&amp;gt; нормализовали детей корня и добавили в корневой список, далее за &amp;lt;tex&amp;gt;O(D(n))+ls&amp;lt;/tex&amp;gt; получили новый корневой список, в котором за &amp;lt;tex&amp;gt;O(D(n))&amp;lt;/tex&amp;gt; нашли минимальный корень и подвесили список за него.&lt;br /&gt;
&lt;br /&gt;
Получили фактическую стоимость &amp;lt;tex&amp;gt;O(D(n))+ls&amp;lt;/tex&amp;gt;. С другой стороны, при добавлении детей в список мы увеличили потенциал &amp;lt;tex&amp;gt;\Phi&amp;lt;/tex&amp;gt; не более чем на &amp;lt;tex&amp;gt;O(D(n))&amp;lt;/tex&amp;gt;, а каждый связывающий шаг уменьшает наш потенциал &amp;lt;tex&amp;gt;\Phi&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Отсюда стоимость &amp;lt;tex&amp;gt;O(D(n))=O(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стоимость &amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== decreaseKey ===&lt;br /&gt;
После уменьшения ключа может быть нарушена [[Двоичная куча|кучеобразность]], в этом случае мы переносим все поддерево с корнем в уменьшаемом элементе в корневой список, также обновляем минимум в тонкой куче.&lt;br /&gt;
&lt;br /&gt;
Теперь могут быть нарушены свойства тонкого дерева, будем различать два вида нарушений:&lt;br /&gt;
* Братские нарушения {{---}} это нарушения [[Тонкая куча#about_thin_tree|третьего свойства]] тонкого дерева.&lt;br /&gt;
* Родительские нарушения {{---}} это нарушения [[Тонкая куча#about_thin_tree|первого или второго свойства]] тонкого дерева.&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;, если ранг узла &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; отличается от ранга его ближайшего правого брата на 2, либо он не имеет правого брата и его ранг равен 1.&lt;br /&gt;
&lt;br /&gt;
Назовем узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; узлом локализации родительского нарушения, если выполнено одно из трех условий:&lt;br /&gt;
# Ранг узла &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; на три больше, чем ранг его самого левого сына.&lt;br /&gt;
# Ранг узла &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; равен двум, и он не имеет детей.&lt;br /&gt;
# Узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; есть тонкий корень дерева.&lt;br /&gt;
&lt;br /&gt;
Пусть узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — это узел локализации братского нарушения.&lt;br /&gt;
* Узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; не тонкий, тогда помещаем поддерево с корнем в самом левом сыне узла &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; на место пропущенного в братском списке. Узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; становится тонким, дерево становится корректным, процедура исправления завершается.&lt;br /&gt;
* Узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; тонкий, тогда уменьшаем ранг узла &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; на единицу. Теперь узлом локализации нарушения будет либо левый брат узла &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, либо его родитель, тогда нарушение станет родительским.&lt;br /&gt;
&lt;br /&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; — родитель узла &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Переместим все поддерево с корнем в &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в корневой список и уменьшим ранг &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; не был старшим братом, то переходим к его левому брату, нарушение станет братским.&lt;br /&gt;
# Если узел &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; был старшим братом, то смотрим на родителя&lt;br /&gt;
#* Узел &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; не был тонким, пометим его как тонкий, тогда дерево станет корректным.&lt;br /&gt;
#* Узел &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; был тонким, тогда &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} новый узел локализации родительского нарушения, переходим к нему.&lt;br /&gt;
&lt;br /&gt;
Продолжая эту процедуру, мы или остановимся, или дойдем до корня дерева, тогда достаточно сделать ранг корня на 1 больше ранга его самого левого сына.&lt;br /&gt;
&lt;br /&gt;
Каждый промежуточный шаг рекурсии уменьшает количество тонких узлов на 1 и добавляет не более одного дерева в корневой список, тогда на каждом промежуточном шаге потенциал уменьшается минимум на 1, отсюда амортизированная стоимость &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;. Также заметим, что мы всегда перемещаемся либо влево, либо вверх по нашему дереву, так что суммарно в худшем случае мы выполним &amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt; операций, а не &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, как в случае фибоначчиевой кучи.&lt;br /&gt;
&lt;br /&gt;
Стоимость &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== delete ===&lt;br /&gt;
Чтобы удалить элемент из тонкой кучи нужно сначала выполнить &amp;lt;tex&amp;gt;\mathtt{decreaseKey}&amp;lt;/tex&amp;gt; этого элемента до &amp;lt;tex&amp;gt;-\infty&amp;lt;/tex&amp;gt;, а затем выполнить &amp;lt;tex&amp;gt;\mathtt{extractMin}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''void''' delete(H: '''ThinHeap''', x: '''Node'''):&lt;br /&gt;
    decreaseKey(H, x, &amp;lt;tex&amp;gt;-\infty&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    extractMin() &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Стоимость &amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Источники =&lt;br /&gt;
* [http://dl.acm.org/citation.cfm?id=1328914 ''Каплан Х.'', ''Тарьян А. Р..'', Thin Heaps, Thick Heaps // ACM Transactions on Algorithms. {{---}} 2008. {{---}} Т.4. {{---}} №1. {{---}} C. 1{{---}}14. {{---}} ISSN: 1549-6325]&lt;br /&gt;
* [http://www.lektorium.tv/lecture/?id=14233 ''Станкевич А. С.'', Дополнительные главы алгоритмов, лекция 1 {{---}} Лекториум]&lt;br /&gt;
* [http://www.intuit.ru/studies/courses/100/100/lecture/1542 Тонкие кучи  — INTUIT.ru]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Структуры данных]]&lt;br /&gt;
[[Категория: Приоритетные очереди]]&lt;/div&gt;</summary>
		<author><name>176.195.102.171</name></author>	</entry>

	</feed>