<?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=213.179.236.72&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=213.179.236.72&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/213.179.236.72"/>
		<updated>2026-04-16T13:53:26Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=B%2B-%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE&amp;diff=70237</id>
		<title>B+-дерево</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=B%2B-%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE&amp;diff=70237"/>
				<updated>2019-03-07T21:37:40Z</updated>
		
		<summary type="html">&lt;p&gt;213.179.236.72: /* Разбиение узла */  Исправлен баг с перемещением mid_key в new_node&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''&amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-дерево''' (англ. ''&amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-tree'') {{---}} структура данных на основе [[B-дерево|B-дерева]], сбалансированное &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-арное дерево поиска с переменным, но зачастую большим количеством потомков в узле. &amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-деревья имеют очень высокий коэффициент ветвления (число указателей из родительского узла на дочерние, обычно порядка &amp;lt;tex&amp;gt;100&amp;lt;/tex&amp;gt; или более), что снижает количество операций ввода-вывода, требующих поиска элемента в дереве.&lt;br /&gt;
&lt;br /&gt;
== Отличия от B-дерева ==&lt;br /&gt;
В &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;-дереве во всех вершинах хранятся ключи вместе с сопутствующей информацией. В &amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-деревьях вся информация хранится в листьях, а во внутренних узлах хранятся только копии ключей. Таким образом удается получить максимально возможную степень ветвления во внутренних узлах. Кроме того, листовой узел может включать в себя указатель на следующий листовой узел для ускорения последовательного доступа, что решает одну из главных проблем &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;-деревьев.&lt;br /&gt;
&lt;br /&gt;
== Структура ==&lt;br /&gt;
Свойства &amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt; дерева аналогичны [[B-дерево#Структура| свойствам &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;-дерева]] (с учетом отличий описанных выше).&lt;br /&gt;
&lt;br /&gt;
=== Структура узла ===&lt;br /&gt;
 '''struct''' Node&lt;br /&gt;
    '''bool''' leaf &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;      // является ли узел листом&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''int'''  key_num &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;   // количество ключей узла&amp;lt;/span&amp;gt;&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;
    '''Node''' parent &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;
    '''Info''' pointers[] &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;       // указатель на левого брата&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;
=== Структура дерева ===&lt;br /&gt;
 '''struct''' BPlusTree&lt;br /&gt;
    '''int'''  t &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;         // минимальная степень дерева&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' root &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;
{{Теорема|statement=Если &amp;lt;tex&amp;gt;n \geqslant 1&amp;lt;/tex&amp;gt;, то для &amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-дерева c &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; узлами и минимальной степенью &amp;lt;tex&amp;gt;t \geqslant 2&amp;lt;/tex&amp;gt; высота&lt;br /&gt;
:&amp;lt;tex&amp;gt;h \leqslant \log_t\dfrac{n}{2} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;n \geqslant 1&amp;lt;/tex&amp;gt;, то корень &amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; содержит хотя бы один ключ, а все остальные узлы — хотя бы &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt; ключей. &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; имеет хотя бы &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; узла на высоте &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, не менее &amp;lt;tex&amp;gt;2t&amp;lt;/tex&amp;gt; узлов на глубине &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;,  и так далее. То есть на глубине &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt;, оно имеет  хотя бы &amp;lt;tex&amp;gt;2t^{h-1}&amp;lt;/tex&amp;gt; узлов. Так как сами ключи хранятся только в листах, а во внутренних вершинах лишь их копии, то для &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; ключей &lt;br /&gt;
&amp;lt;tex&amp;gt;n \geqslant 2t^{h-1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;t^{h-1} \leqslant \dfrac{n}{2}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;h-1 \leqslant \log_t\dfrac{n}{2}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;h \leqslant \log_t\dfrac{n}{2} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
}} &lt;br /&gt;
&lt;br /&gt;
Как можно заметить, высота &amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-дерева не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; отличается от [[B-дерево#Высота|высоты &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;-дерева]], то есть хранение информации только в листах почти не ухудшает эффективность дерева &lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
&amp;lt;tex&amp;gt;B^{+}&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;
 '''Node''' find_leaf(T: '''BPlusTree''', key: '''int'''):&lt;br /&gt;
     cur = T.root&lt;br /&gt;
     '''while''' cur.leaf &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; true&lt;br /&gt;
         '''for''' i = 0 '''to''' cur.key_num&lt;br /&gt;
             '''if''' i == cur.key_num '''or''' key &amp;lt; cur.key[i]&lt;br /&gt;
                 cur = cur.child[i]&lt;br /&gt;
                 '''break'''&lt;br /&gt;
     '''return''' cur&lt;br /&gt;
&lt;br /&gt;
=== Поиск === &lt;br /&gt;
Находим нужный лист через &amp;lt;tex&amp;gt;find&amp;lt;/tex&amp;gt;_&amp;lt;tex&amp;gt;leaf&amp;lt;/tex&amp;gt; и ищем нужный ключ в нем&lt;br /&gt;
&lt;br /&gt;
=== Добавление ключа ===&lt;br /&gt;
Ищем лист, в который можно добавить ключ и добавляем его в список ключей. Если узел не заполнен, то добавление завершено. Иначе разбиваем узел на два узла. Будем считать, что в дереве не может находиться &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; одинаковых ключа, поэтому &amp;lt;tex&amp;gt;insert&amp;lt;/tex&amp;gt; будет возвращать был ли добавлен ключ.&lt;br /&gt;
&lt;br /&gt;
 '''bool''' insert(T: '''BPlusTree''', key: '''int''', value: '''Info'''):&lt;br /&gt;
     leaf = find_key(T, key)&lt;br /&gt;
     '''if''' key &amp;lt;tex&amp;gt;\in&amp;lt;/tex&amp;gt; leaf&lt;br /&gt;
         '''return false'''  &lt;br /&gt;
     &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Ищем позицию для нового ключа &amp;lt;/span&amp;gt;&lt;br /&gt;
     pos = 0&lt;br /&gt;
     '''while''' pos &amp;lt; leaf.key_num '''and''' leaf.key[pos] &amp;lt; key&lt;br /&gt;
         ++pos&lt;br /&gt;
       &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Вставляем ключ&amp;lt;/span&amp;gt;&lt;br /&gt;
     '''for''' i = leaf.key_num '''downto''' pos + 1 &lt;br /&gt;
         leaf.key[i] = leaf.key[i - 1]&lt;br /&gt;
         leaf.pointers[i] = leaf.pointer[i - 1]&lt;br /&gt;
     leaf.key[pos] = key&lt;br /&gt;
     leaf.pointers[pos] = value&lt;br /&gt;
     ++leaf.key_num&lt;br /&gt;
     &lt;br /&gt;
     '''if''' leaf.key_num == 2 * t &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;             // t {{---}} степень дерева&amp;lt;/span&amp;gt;&lt;br /&gt;
         split(T, leaf)             &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;      // Разбиваем узел&amp;lt;/span&amp;gt;&lt;br /&gt;
     '''return true'''&lt;br /&gt;
&lt;br /&gt;
=== Разбиение узла ===&lt;br /&gt;
Разбиение на два узла происходит следующим образом: в первый добавляем первые &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; ключей, во второй последние &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Если узел {{---}} лист, то оставшийся ключ также добавляется в правое поддерево, а его копия отправляется в родительский узел, где становится разделительной точкой для двух новых поддеревьев. &lt;br /&gt;
&lt;br /&gt;
Если и родительский узел заполнен {{---}} поступаем аналогично, но не копируем, а просто перемещаем оставшийся перемещаем ключ в родительский узел, так как это просто копия. Повторяем пока не встретим незаполненный узел или не дойдем до корня. В последнем случае корень разбивается на два узла и высота дерева увеличивается.&lt;br /&gt;
&lt;br /&gt;
Поскольку в родителя всегда отправляется минимальный ключ из второй половины, то каждый ключ, который хранится во внутренней вершине {{---}} это минимум правого поддерева для этого ключа.&lt;br /&gt;
&lt;br /&gt;
[[Файл:B Plus tree insetring.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''void''' split(T: '''BPlusTree''', node: '''Node'''):&lt;br /&gt;
     new_node = new_Node() &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                 //Создаем новый узел&amp;lt;/span&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Перенаправляем right и left указатели&amp;lt;/span&amp;gt;&lt;br /&gt;
     new_node.right = node.right&lt;br /&gt;
     node.right.left = new_node&lt;br /&gt;
     node.right = new_node&lt;br /&gt;
     new_node.left = node&lt;br /&gt;
     &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Перемещаем t - 1 значений и соответствующих им указателей в new_node&amp;lt;/span&amp;gt;&lt;br /&gt;
     mid_key = node.key[t]&lt;br /&gt;
     new_node.key_num = t - 1&lt;br /&gt;
     node.key_num = t&lt;br /&gt;
     '''for''' i = 0 '''to''' new_node.key_num - 1&lt;br /&gt;
         new_node.key[i] = node.key[i + t + 1]&lt;br /&gt;
         new_node.pointers[i] = node.pointers[i + t + 1]  &lt;br /&gt;
         new_node.child[i] = node.child[i + t + 1]    &lt;br /&gt;
     new_node.child[new_node.key_num] = node.child[2 * t]  &lt;br /&gt;
     &lt;br /&gt;
     '''if''' node.leaf&lt;br /&gt;
         ++new_node.key_num&lt;br /&gt;
         new_node.leaf = '''true'''&lt;br /&gt;
         &lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Перемещаем в new_node оставшийся при разбиении элемент mid_key &amp;lt;/span&amp;gt;&lt;br /&gt;
         '''for''' i = new_node.key_num - 1 '''downto''' 1&lt;br /&gt;
             new_node.key[i] = new_node.key[i - 1]&lt;br /&gt;
             new_node.pointers[i] = new_node.pointers[i - 1]&lt;br /&gt;
         new_node.key[0] = node.key[t]&lt;br /&gt;
         new_node.pointers[0] = node.pointers[t]&lt;br /&gt;
     &lt;br /&gt;
     '''if''' node == T.root&lt;br /&gt;
         T.root = new_Node() &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                 // Создаем новый корень T.root &amp;lt;/span&amp;gt;&lt;br /&gt;
         T.root.key[0] = mid_key&lt;br /&gt;
         T.root.child[0] = node&lt;br /&gt;
         T.root.child[1] = new_node&lt;br /&gt;
         T.root.key_num = 1;&lt;br /&gt;
         node.parent = T.root&lt;br /&gt;
         new_node.parent = T.root&lt;br /&gt;
     '''else'''&lt;br /&gt;
         new_node.parent = node.parent&lt;br /&gt;
         parent = node.parent&lt;br /&gt;
         &lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Ищем позицию mid_key в отце &amp;lt;/span&amp;gt;&lt;br /&gt;
         pos = 0&lt;br /&gt;
         '''while''' pos &amp;lt; parent.key_num '''and''' parent.key[pos] &amp;lt; mid_key&lt;br /&gt;
             ++pos&lt;br /&gt;
         &lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Добавляем mid_key в отца и направляем ссылку из него на new_node &amp;lt;/span&amp;gt;&lt;br /&gt;
         '''for''' i = parent.key_num '''downto''' pos + 1 &lt;br /&gt;
             parent.key[i] = parent.key[i - 1]&lt;br /&gt;
         '''for''' i = parent.key_num + 1 '''downto''' pos + 2 &lt;br /&gt;
             parent.child[i] = parent.child[i - 1]&lt;br /&gt;
         parent.key[pos] = mid_key&lt;br /&gt;
         parent.child[pos + 1] = new_node&lt;br /&gt;
         ++parent.key_num&lt;br /&gt;
         &lt;br /&gt;
         '''if''' parent.key_num == 2 * t &lt;br /&gt;
             split(T, parent)&lt;br /&gt;
&lt;br /&gt;
=== Удаление ===&lt;br /&gt;
Поскольку все ключи находятся в листах, для удаления в первую очередь необходимо найти листовой узел, в котором он находится. Если узел содержит не менее &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt; ключей, где &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; {{---}} это степень дерева, то удаление завершено. Иначе необходимо выполнить попытку перераспределения элементов, то есть добавить в узел элемент из левого или правого брата (не забыв обновить информацию в родителе). Если это невозможно, необходимо выполнить слияние с братом и удалить ключ, который указывает на удалённый узел. Объединение может распространяться на корень, тогда происходит уменьшение высоты дерева. Так как мы считаем, что в дереве не может находиться &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; одинаковых ключей, то &amp;lt;tex&amp;gt;delete&amp;lt;/tex&amp;gt; будет возвращать был ли удален ключ.&lt;br /&gt;
&lt;br /&gt;
[[Файл:B-Tree-Deletions.gif]]&lt;br /&gt;
&lt;br /&gt;
 '''bool''' delete(T: '''BPlusTree''', key: '''int'''):&lt;br /&gt;
     leaf = find_key(T, key)&lt;br /&gt;
     pos = 0&lt;br /&gt;
     '''if''' key &amp;lt;tex&amp;gt;\notin&amp;lt;/tex&amp;gt; leaf&lt;br /&gt;
         '''return false''' &lt;br /&gt;
     '''else''' &lt;br /&gt;
         delete_in_node(leaf, key)                   &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt; // Удалить ключ из вершины&amp;lt;/span&amp;gt;&lt;br /&gt;
         '''return true'''&lt;br /&gt;
&lt;br /&gt;
 '''void''' delete_in_node(tec: '''Node''', key: '''int'''):&lt;br /&gt;
     '''if''' key &amp;lt;tex&amp;gt;\notin&amp;lt;/tex&amp;gt; tec&lt;br /&gt;
         '''return''' &lt;br /&gt;
      &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Ищем позицию удаляемого ключа &amp;lt;/span&amp;gt;&lt;br /&gt;
     pos = 0&lt;br /&gt;
     '''while''' pos &amp;lt; tec.key_num '''and''' tec.key[pos] &amp;lt; key&lt;br /&gt;
         ++pos&lt;br /&gt;
      &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Удаляем ключ&amp;lt;/span&amp;gt;&lt;br /&gt;
     '''for''' i = pos '''to''' tec.key_num - 1 &lt;br /&gt;
         tec.key[i] = tec.key[i + 1]&lt;br /&gt;
         tec.pointers[i] = tec.pointer[i + 1]&lt;br /&gt;
     '''for''' i = pos + 1 '''to''' tec.key_num &lt;br /&gt;
         tec.child[i] = tec.child[i + 1]&lt;br /&gt;
     --tec.key_num&lt;br /&gt;
     &lt;br /&gt;
     '''if''' leaf.key_num &amp;lt; t - 1&lt;br /&gt;
         right_sibling = tec.right&lt;br /&gt;
         left_sibling = tec.left&lt;br /&gt;
         '''if''' left_sibling &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; null '''and''' left_sibling.key_num &amp;gt; t - 1&lt;br /&gt;
             --left_sibling.key_num&lt;br /&gt;
             ++tec.key_num&lt;br /&gt;
      &lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Перемещаем максимальный из left_sibling ключ на первую позицию в tec &amp;lt;/span&amp;gt;&lt;br /&gt;
             '''for''' i = 1 '''to''' tec.key_num - 1 &lt;br /&gt;
                 tec.key[i] = tec.key[i - 1]&lt;br /&gt;
                 tec.pointers[i] = tec.pointer[i - 1] &lt;br /&gt;
                 tec.child[i] = tec.child[i - 1]&lt;br /&gt;
             tec.child[tec.key_num] = tec.child[tec.key_num - 1]&lt;br /&gt;
             tec.key[0] = left_sibling.key[left_sibling.key_num]&lt;br /&gt;
             tec.pointers[0] = left_sibling.pointers[left_sibling.key_num]&lt;br /&gt;
             tec.child[0] = left_sibling.child [left_sibling.key_num + 1]&lt;br /&gt;
             &lt;br /&gt;
             update(tec)                     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                                   // Обновить ключи на пути к корню&amp;lt;/span&amp;gt;&lt;br /&gt;
         &lt;br /&gt;
         '''else if''' right_sibling &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; null '''and''' right_sibling.key_num &amp;gt; t - 1&lt;br /&gt;
             --right_sibling.key_num&lt;br /&gt;
             ++tec.key_num&lt;br /&gt;
      &lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Перемещаем минимальный из right_sibling ключ на последнюю позицию в tec &amp;lt;/span&amp;gt;&lt;br /&gt;
             tec.key[tec.key_num - 1] = right_sibling.key[0]&lt;br /&gt;
             tec.pointers[tec.key_num - 1] = right_sibling.child[0]&lt;br /&gt;
             tec.child[tec.key_num - 1] = right_sibling.pointers[0]&lt;br /&gt;
              &lt;br /&gt;
             update(tec)                     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                                   // Обновить ключи на пути к корню&amp;lt;/span&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
         '''else'''&lt;br /&gt;
             '''if''' left_sibling &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; null &lt;br /&gt;
                &lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Сливаем tec и left_sibling&amp;lt;/span&amp;gt;&lt;br /&gt;
                 '''for''' i = 0 to tec.key_num - 1&lt;br /&gt;
                     left_sibling.key[left_sibling.key_num] = tec.key[i]&lt;br /&gt;
                     left_sibling.pointers[left_sibling.key_num] = tec.pointers[i]&lt;br /&gt;
                     left_sibling.child[left_sibling.key_num + 1] = tec.child[i]&lt;br /&gt;
                     ++left_sibling.key_num&lt;br /&gt;
                 left_sibling.child[left_sibling.key_num + 1] = tec.child[tec.key_num]&lt;br /&gt;
                  &lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Перенаправляем right и left указатели&amp;lt;/span&amp;gt;&lt;br /&gt;
                 left_sibling.right = tec.right&lt;br /&gt;
                 tec.right.left = left_sibling &lt;br /&gt;
                 &lt;br /&gt;
                 update(left_sibling)                      &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                      // Обновить ключи на пути к корню&amp;lt;/span&amp;gt;&lt;br /&gt;
                 delete_in_node(left_sibling.parent, min_key(tec))  &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;             // Удаляем разделительный ключ в отце&amp;lt;/span&amp;gt;&lt;br /&gt;
              &lt;br /&gt;
             '''else'''&lt;br /&gt;
                 &lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Сливаем tec и right_sibling&amp;lt;/span&amp;gt;&lt;br /&gt;
                 '''for''' i = 0 to tec.key_num - 1&lt;br /&gt;
                     tec.key[tec.key_num] = right_sibling.key[i]&lt;br /&gt;
                     tec.pointers[tec.key_num] = right_sibling.pointers[i]&lt;br /&gt;
                     tec.child[tec.key_num + 1] = right_sibling.child[i]&lt;br /&gt;
                     ++tec.key_num&lt;br /&gt;
                 tec.child[tec.key_num + 1] = right_sibling.child[right_sibling.key_num]&lt;br /&gt;
                  &lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// Перенаправляем right и left указатели&amp;lt;/span&amp;gt;&lt;br /&gt;
                 right_sibling.right.left = tec &lt;br /&gt;
                 tec.right = right_sibling.right&lt;br /&gt;
                  &lt;br /&gt;
                 update(tec)                      &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                               // Обновить ключи на пути к корню&amp;lt;/span&amp;gt;&lt;br /&gt;
                 delete_in_node(tec.parent, min_key(right_sibling))   &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;           // Удаляем разделительный ключ в отце&amp;lt;/span&amp;gt;&lt;br /&gt;
              &lt;br /&gt;
         '''if''' T.root.key_num == 1&lt;br /&gt;
             T.root = T.root.child[0]&lt;br /&gt;
&lt;br /&gt;
== Где используется ==&lt;br /&gt;
Изначально структура предназначалась для эффективного поиска в блочно-ориентированной среде хранения {{---}} в частности, для файловых систем. Структура широко применяется в таких файловых системах, как NTFS&amp;lt;ref&amp;gt;[[wikipedia:NTFS |Wikipedia {{---}} NTFS]]&amp;lt;/ref&amp;gt;, ReiserFS&amp;lt;ref&amp;gt;[[wikipedia:ReiserFS |Wikipedia {{---}} ReiserFS]]&amp;lt;/ref&amp;gt;, NSS&amp;lt;ref&amp;gt;[[wikipedia:Novell Storage Services |Wikipedia {{---}} NSS]]&amp;lt;/ref&amp;gt;, JFS&amp;lt;ref&amp;gt;[[wikipedia:JFS (file system) |Wikipedia {{---}} JFS]]&amp;lt;/ref&amp;gt;, ReFS&amp;lt;ref&amp;gt;[[wikipedia:ReFS |Wikipedia {{---}} ReFS]]&amp;lt;/ref&amp;gt;. Различные реляционные системы управления базами данных, такие как  Microsoft SQL Server&amp;lt;ref&amp;gt;[[wikipedia:Microsoft SQL Server|Wikipedia {{---}} Microsoft SQL Server]]&amp;lt;/ref&amp;gt;, Oracle Database&amp;lt;ref&amp;gt;[[wikipedia:Oracle Database|Wikipedia {{---}} Oracle Database]]&amp;lt;/ref&amp;gt;, SQLite&amp;lt;ref&amp;gt;[[wikipedia:SQLite|Wikipedia {{---}} SQLite]]&amp;lt;/ref&amp;gt; используют &amp;lt;tex&amp;gt;B^{+}&amp;lt;/tex&amp;gt;-деревья для табличных индексов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[B-дерево]]&lt;br /&gt;
* [[2-3 дерево]]&lt;br /&gt;
&lt;br /&gt;
== Примeчания ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Д. Кнут «Искусство программирования. Сортировка и поиск», часть 6.2.4&lt;br /&gt;
* [https://en.wikipedia.org/wiki/B%2B_tree Wikipedia {{---}} B Plus tree]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/B-tree Wikipedia {{---}} B tree]&lt;br /&gt;
* [https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html B plus tree visualization]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Структуры данных]]&lt;br /&gt;
[[Категория: Деревья поиска]]&lt;/div&gt;</summary>
		<author><name>213.179.236.72</name></author>	</entry>

	</feed>