<?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=5.18.213.18&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=5.18.213.18&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/5.18.213.18"/>
		<updated>2026-04-15T21:19:07Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%B2%D0%B0%D0%BD_%D0%AD%D0%BC%D0%B4%D0%B5_%D0%91%D0%BE%D0%B0%D1%81%D0%B0&amp;diff=60608</id>
		<title>Дерево ван Эмде Боаса</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%B2%D0%B0%D0%BD_%D0%AD%D0%BC%D0%B4%D0%B5_%D0%91%D0%BE%D0%B0%D1%81%D0%B0&amp;diff=60608"/>
				<updated>2017-03-26T16:20:14Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.213.18: /* remove */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Дерево ван Эмде Боаса''' (англ. ''Van Emde Boas tree, vEB tree'') {{---}} структура данных, представляющая собой [[Дерево поиска, наивная реализация|дерево поиска]], позволяющее хранить целые неотрицательные числа в интервале &amp;lt;tex&amp;gt;[0;2^k)&amp;lt;/tex&amp;gt; и осуществлять над ними все соответствующие дереву поиска операции.&lt;br /&gt;
&lt;br /&gt;
Проще говоря, данная структура позволяет хранить &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-битные числа и производить над ними операции &amp;lt;tex&amp;gt;\mathrm{find}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{insert}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{remove}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{next}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{prev}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{\min}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{max}&amp;lt;/tex&amp;gt; и некоторые другие операции, которые присущи всем деревьям поиска.&lt;br /&gt;
&lt;br /&gt;
Особенностью этой структуры является то, что все операции выполняются за &amp;lt;tex&amp;gt;O(\log k)&amp;lt;/tex&amp;gt;, что асимптотически лучше, чем &amp;lt;tex&amp;gt;O(\log 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;
[[Файл:Дерево_ван_Эмде_Боаса.png|right|680px|thumb|4-дерево, содержащее в себе 0, 1, 2, 3, 5, 14 и 15. Красным цветом выделены непустые поддеревья]]&lt;br /&gt;
&lt;br /&gt;
Для удобства работы с деревом будем использовать &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, равные степени двойки.&lt;br /&gt;
&lt;br /&gt;
Как уже было сказано выше, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-дерево хранит числа в интервале &amp;lt;tex&amp;gt;[0;2^k)&amp;lt;/tex&amp;gt;. Тогда при &amp;lt;tex&amp;gt;k = 1&amp;lt;/tex&amp;gt; дерево хранит информацию, содержатся ли в нем &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-дерево, при &amp;lt;tex&amp;gt;k \neq 1&amp;lt;/tex&amp;gt;. В нем будут хранится:&lt;br /&gt;
*массив &amp;lt;tex&amp;gt;children&amp;lt;/tex&amp;gt;, состоящий из &amp;lt;tex&amp;gt;2^{k/2}&amp;lt;/tex&amp;gt;  &amp;lt;tex&amp;gt;k/2&amp;lt;/tex&amp;gt;-деревьев&lt;br /&gt;
*вспомогательное &amp;lt;tex&amp;gt;k/2&amp;lt;/tex&amp;gt;-дерево, которое назовем &amp;lt;tex&amp;gt;aux&amp;lt;/tex&amp;gt;&lt;br /&gt;
*максимальный и минимальный элементы, хранящиеся в этом дереве (если оно не является пустым), причем дополнительно в массиве &amp;lt;tex&amp;gt; chilren &amp;lt;/tex&amp;gt; эти элементы хранить не будем.&lt;br /&gt;
&lt;br /&gt;
Пусть у нас есть &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-битное число &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Разобьем это число таким образом, что &amp;lt;tex&amp;gt;\mathrm{high(x)}&amp;lt;/tex&amp;gt; {{---}} число, соответствующее &amp;lt;tex&amp;gt;k/2&amp;lt;/tex&amp;gt; старшим битам числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;\mathrm{low(x)}&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;k/2&amp;lt;/tex&amp;gt; младшим битам. Тогда информация, хранится ли в данном дереве число &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, эквивалентна информации, содержится ли в дереве &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;\mathrm{low(x)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Нетрудно увидеть, что высота подобного дерева &amp;lt;tex&amp;gt;\log_{2} k&amp;lt;/tex&amp;gt;, так как каждый следующий уровень дерева содержит числа, количество битов в которых в 2 раза меньше, чем в предыдущем.&lt;br /&gt;
&lt;br /&gt;
Во вспомогательном дереве &amp;lt;tex&amp;gt;aux&amp;lt;/tex&amp;gt; будем хранить все такие числа &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt;, что дерево &amp;lt;tex&amp;gt;children[p]&amp;lt;/tex&amp;gt; не пусто.&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
=== empty ===&lt;br /&gt;
Чтобы определить, пусто ли дерево, будем изначально инициализировать поле &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; числом, которое не лежит в интервале &amp;lt;tex&amp;gt;[0;2^k)&amp;lt;/tex&amp;gt;. Назовем это число &amp;lt;tex&amp;gt;none&amp;lt;/tex&amp;gt;. Например, это может быть &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;, если мы храним в числа в знаковом целочисленном типе, или &amp;lt;tex&amp;gt;2^k&amp;lt;/tex&amp;gt;, если в беззнаковом. Тогда проверка на пустоту дерева будет заключаться лишь в сравнении поля &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; с этим числом.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''boolean''' empty(t: '''Tree'''):&lt;br /&gt;
  '''if''' t.min == ''none''&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
  '''else'''&lt;br /&gt;
   '''return''' ''false''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== min и max ===&lt;br /&gt;
Так как мы храним в дереве минимальное и максимальное значения, то данные операции не требуют ничего, кроме вывода значения поля &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;\max&amp;lt;/tex&amp;gt; в соответствии с запросом. Время выполнения данных операций соответственно &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== find ===&lt;br /&gt;
Алгоритм поиска сам напрашивается из выше описанной структуры:&lt;br /&gt;
*если дерево пусто, то число не содержится в нашей структуре.&lt;br /&gt;
*если число равно полю &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;\max&amp;lt;/tex&amp;gt;, то число в дереве есть.&lt;br /&gt;
*иначе ищем число &amp;lt;tex&amp;gt;\mathrm{low(x)}&amp;lt;/tex&amp;gt; в поддереве &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''boolean''' find(t: '''Tree''', x: '''int'''):&lt;br /&gt;
  '''if''' empty(t)&lt;br /&gt;
    '''return''' ''false''&lt;br /&gt;
  '''if''' t.min == x '''or''' t.max == x&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
  '''return''' find(t.children[high(x)], low(x))&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что выполняя операцию &amp;lt;tex&amp;gt;\mathrm{find}&amp;lt;/tex&amp;gt;, мы либо спускаемся по дереву на один уровень ниже, либо, если нашли нужный нам элемент, выходим из нее. В худшем случае мы спустимся от корня до какого-нибудь 1-дерева, то есть выполним операцию &amp;lt;tex&amp;gt;\mathrm{find}&amp;lt;/tex&amp;gt; столько раз, какова высота нашего дерева. На каждом уровне мы совершаем &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; операций. Следовательно время работы &amp;lt;tex&amp;gt;O(\log k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== insert ===&lt;br /&gt;
Операция вставки элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; состоит из нескольких частей:&lt;br /&gt;
&lt;br /&gt;
*если дерево пусто или в нем содержится единственный элемент (&amp;lt;tex&amp;gt; \min = \max &amp;lt;/tex&amp;gt;), то присвоим полям &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\max&amp;lt;/tex&amp;gt; соответствующие значения. Делать что-то еще бессмысленно, так как информация записанная в &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\max&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;\max&amp;lt;/tex&amp;gt; или меньше &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; текущего дерева, то обновим соответствующее значение минимума или максимума, а старый минимум или максимум добавим в дерево.&lt;br /&gt;
**вставим во вспомогательное дерево &amp;lt;tex&amp;gt;aux&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;\mathrm{high(x)}&amp;lt;/tex&amp;gt;, если соответствующее поддерево &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt; до этого было пусто.&lt;br /&gt;
**вставим число &amp;lt;tex&amp;gt;\mathrm{low(x)}&amp;lt;/tex&amp;gt; в поддерево &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt;, за исключением ситуации, когда текущее дерево {{---}} это 1-дерево, и дальнейшая вставка не требуется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' insert(t: '''Tree''', x: '''int'''):&lt;br /&gt;
  '''if''' empty(t)                                     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// проверка на пустоту текущего дерева&amp;lt;/span&amp;gt;&lt;br /&gt;
    t.min = x&lt;br /&gt;
    t.max = x&lt;br /&gt;
  '''else'''&lt;br /&gt;
    '''if''' t.min == t.max                             &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// проверка, что в дереве один элемент&amp;lt;/span&amp;gt;&lt;br /&gt;
      '''if''' T.min &amp;lt; x&lt;br /&gt;
        t.max = x&lt;br /&gt;
      '''else'''&lt;br /&gt;
        t.min = x&lt;br /&gt;
   '''else'''&lt;br /&gt;
      '''if''' t.min &amp;gt; x&lt;br /&gt;
        swap(t.min, x)                           &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// релаксация минимума&amp;lt;/span&amp;gt;&lt;br /&gt;
      '''if''' t.max &amp;lt; x&lt;br /&gt;
        swap(t.max, x)                           &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// релаксация максимума&amp;lt;/span&amp;gt;&lt;br /&gt;
      '''if''' t.k != 1&lt;br /&gt;
        '''if''' empty(t.children[high(x)])&lt;br /&gt;
          insert(t.aux, high(x))                 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// вставка high(x) во вспомогательно дерево aux&amp;lt;/span&amp;gt;&lt;br /&gt;
        insert(t.children[high(x)], low(x))      &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// вставка low(x) в поддерево children[high(x)]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нетрудно увидеть, что данная операция работает за время &amp;lt;tex&amp;gt;O(\log k)&amp;lt;/tex&amp;gt;. На каждом уровне дерева мы выполняем &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; операций. После этого возможны 2 случая: поддерево &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt; пусто, и мы будем производить дальнейшую вставку и в него, и во вспомогательное дерево &amp;lt;tex&amp;gt;aux&amp;lt;/tex&amp;gt;, или же поддерево не пусто, и мы просто спустимся на уровень ниже. Но если поддерево &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt; пусто, то вставка в него будет выполнена за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, так как мы всего лишь обновим поля &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\max&amp;lt;/tex&amp;gt;. Все остальные операции будут выполнятся уже со вспомогательным деревом &amp;lt;tex&amp;gt;aux&amp;lt;/tex&amp;gt;, высота которого на 1 уровень меньше, чем высота текущего. Если же поддерево &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt; не пусто, то мы просто перейдем к вставке элемента в это поддерево, высота которого так же на 1 меньше, чем у текущего. В итоге, каждый раз, выполнив &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; операций, мы переходим к дереву, высота которого на 1 меньше, чем у текущего. Следовательно, количество операций пропорционально высоте дерева, которая, как уже было показано, &amp;lt;tex&amp;gt;O(\log k)&amp;lt;/tex&amp;gt;. То есть операция вставки займет &amp;lt;tex&amp;gt;O(\log k)&amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
&lt;br /&gt;
=== remove ===&lt;br /&gt;
Удаление из дерева также делится на несколько подзадач:&lt;br /&gt;
*если &amp;lt;tex&amp;gt; \min =  \max = x &amp;lt;/tex&amp;gt;, значит в дереве один элемент, удалим его и отметим, что дерево пусто.&lt;br /&gt;
*если &amp;lt;tex&amp;gt; x = \min &amp;lt;/tex&amp;gt;, то мы должны найти следующий минимальный элемент в этом дереве, присвоить &amp;lt;tex&amp;gt;\min&amp;lt;/tex&amp;gt; значение второго минимального элемента и удалить его из того места, где он хранится. Второй минимум {{---}} это либо &amp;lt;tex&amp;gt; \max &amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt; children[aux.min].min &amp;lt;/tex&amp;gt; (для случая &amp;lt;tex&amp;gt; x = \max &amp;lt;/tex&amp;gt; действуем аналогично).&lt;br /&gt;
*если же &amp;lt;tex&amp;gt; x \neq \min &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; x \neq \max &amp;lt;/tex&amp;gt;, то мы должны удалить &amp;lt;tex&amp;gt;\mathrm{low(x)}&amp;lt;/tex&amp;gt; из поддерева &amp;lt;tex&amp;gt;children[\mathrm{high(x)}]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Так как в поддеревьях хранятся не все биты исходных элементов, а только часть их, то для восстановления исходного числа, по имеющимся старшим и младшим битам, будем использовать функцию &amp;lt;tex&amp;gt; merge &amp;lt;/tex&amp;gt;. Также нельзя забывать, что если мы удаляем последнее вхождение &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, то мы должны удалить &amp;lt;tex&amp;gt;\mathrm{high(x)}&amp;lt;/tex&amp;gt; из вспомогательного дерева.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''function''' remove(t: '''Tree''', x: '''int'''):&lt;br /&gt;
  '''if''' t.min == x '''and''' t.max == x              &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// случай, когда в дереве один элемент&amp;lt;/span&amp;gt;&lt;br /&gt;
    t.min = ''none''&lt;br /&gt;
    '''return'''&lt;br /&gt;
  '''if''' t.min == x&lt;br /&gt;
    '''if''' empty(t.aux)&lt;br /&gt;
      t.min = t.max&lt;br /&gt;
      '''return'''&lt;br /&gt;
    x = merge(t.aux.min, t.children[t.aux.min].min)&lt;br /&gt;
    t.min = x&lt;br /&gt;
  '''if''' t.max == x&lt;br /&gt;
    '''if''' empty(t.aux)&lt;br /&gt;
      t.max = t.min&lt;br /&gt;
      '''return'''&lt;br /&gt;
  '''else'''&lt;br /&gt;
      x = merge(t.aux.max, t.children[t.aux.max].max)&lt;br /&gt;
      t.max = x&lt;br /&gt;
  '''if''' empty(t.aux)                           &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// случай, когда элемента x нет в дереве&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''return'''&lt;br /&gt;
  remove(t.children[high(x)], low(x))&lt;br /&gt;
  '''if''' empty(t.children[high(x)])             &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// если мы удалили из поддерева последний элемент&amp;lt;/span&amp;gt;&lt;br /&gt;
    remove(t.aux, high(x))                  &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// то удаляем информацию, что это поддерево не пусто&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка времени работы операции &amp;lt;tex&amp;gt;\mathrm{remove}&amp;lt;/tex&amp;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; операций и переходим к удалению элементов максимум в двух деревьях(в одном поддереве и во вспомогательном дереве), чьи высоты на один меньше текущей. Но если мы производим операцию удаления из вспомогательного дерева, значит удаление из поддерева потребовало &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; операций, так как оно содержало всего один элемент. В итоге, количество операций пропорционально высоте дерева, то есть &amp;lt;tex&amp;gt;O(\log k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== next и prev ===&lt;br /&gt;
Алгоритм нахождения следующего элемента, как и два предыдущих, сводится к рассмотрению случая, когда дерево содержит не более одного элемента, либо к поиску в одном из его поддеревьев:&lt;br /&gt;
*если дерево пусто, или максимум этого дерева не превосходит &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt;, то следующего элемента в этом дереве не существует.&lt;br /&gt;
*если &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; меньше поля &amp;lt;tex&amp;gt; \min &amp;lt;/tex&amp;gt;, то искомый элемент и есть &amp;lt;tex&amp;gt; \min &amp;lt;/tex&amp;gt;.&lt;br /&gt;
*если дерево содержит не более двух элементов, и &amp;lt;tex&amp;gt; x &amp;lt; \max &amp;lt;/tex&amp;gt;, то искомый элемент &amp;lt;tex&amp;gt; \max &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;\mathrm{high(x)} &amp;lt;/tex&amp;gt;, то продолжим поиск в поддереве &amp;lt;tex&amp;gt; children[\mathrm{high(x)}] &amp;lt;/tex&amp;gt;, где будем искать число, следующее после &amp;lt;tex&amp;gt;\mathrm{low(x)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
**иначе искомым элементом является либо минимум следующего непустого поддерева, если такое есть, либо максимум текущего дерева в противном случае.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 '''int''' next(t: '''Tree''', x: '''int''')&lt;br /&gt;
  '''if''' empty(t) '''or''' t.max &amp;lt;= x&lt;br /&gt;
    '''return''' ''none'';                                                          &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// следующего элемента нет&amp;lt;/span&amp;gt;&lt;br /&gt;
  '''if''' t.min &amp;gt; x&lt;br /&gt;
    '''return''' t.min;&lt;br /&gt;
  '''if''' empty(t.aux)&lt;br /&gt;
    '''return''' t.max;                                                         &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// в дереве не более двух элементов&amp;lt;/span&amp;gt;&lt;br /&gt;
  '''else'''&lt;br /&gt;
    '''if''' '''not''' empty(t.children[high(x)]) '''and '''t.childen[high(x)].max &amp;gt; low(x) &lt;br /&gt;
      '''return''' merge(high(x), next(t.children[high(x)], low(x)));           &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// случай, когда следующее число начинается с high(x)&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''else'''                                                                  &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// иначе найдем следующее непустое поддерево&amp;lt;/span&amp;gt; &lt;br /&gt;
      '''int''' nextHigh = next(t.aux, high(x));&lt;br /&gt;
      '''if''' nextHigh == -1&lt;br /&gt;
        '''return''' t.max;                                                     &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// если такого нет, вернем максимум&amp;lt;/span&amp;gt;&lt;br /&gt;
     '''else'''&lt;br /&gt;
        '''return''' merge(nextHigh, t.children[nextHigh].min);                &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt; // если есть, вернем минимум найденного поддерева&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Время работы, как и всех предыдущих функций, оценивается так же, и равно &amp;lt;tex&amp;gt;O(\log k)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;\mathrm{prev} &amp;lt;/tex&amp;gt; реализуется аналогично.&lt;br /&gt;
&lt;br /&gt;
== Преимущества и недостатки ==&lt;br /&gt;
&lt;br /&gt;
=== Преимущества ===&lt;br /&gt;
Главным преимуществом данной структуры является ее быстродействие. Асимптотически время работы операций дерева ван Эмде Боаса лучше, чем, например, у [[АВЛ-дерево|АВЛ]], [[Красно-черное дерево|красно-черных]], [[2-3 дерево|2-3]], [[Splay-дерево|splay]] и [[Декартово дерево|декартовых]] деревьев уже при небольшом количестве элементов. Конечно, из-за довольно непростой реализации возникают немалые постоянные множители, которые снижают практическую эффективность данной структуры. Но все же, при большом количестве элементов, эффективность дерева ван Эмде Боаса проявляется и на практике, что позволяет нам использовать данную структуру не только как эффективное дерево поиска, но и в других задачах. Например:&lt;br /&gt;
*cортировка последовательности из &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; чисел. Вставим элементы в дерево, найдем минимум и &amp;lt;tex&amp;gt; n - 1&amp;lt;/tex&amp;gt; раз вызовем функцию &amp;lt;tex&amp;gt; \mathrm{next} &amp;lt;/tex&amp;gt;. Так как все операции занимают не более &amp;lt;tex&amp;gt; O(\log k)&amp;lt;/tex&amp;gt; времени, то итоговая асимптотика алгоритма &amp;lt;tex&amp;gt; O(n \cdot \log k)&amp;lt;/tex&amp;gt;, что даже лучше, чем [[Цифровая сортировка|цифровая сортировка]], асимптотика которой &amp;lt;tex&amp;gt; O(n \cdot k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
*[[Алгоритм Дейкстры|алгоритм Дейкстры]]. Данный алгоритм с использованием [[Двоичная куча|двоичной кучи]] для поиска минимума работает за &amp;lt;tex&amp;gt; O(E \cdot \log V)&amp;lt;/tex&amp;gt;, где  &amp;lt;tex&amp;gt; V &amp;lt;/tex&amp;gt; {{---}} количество вершин в графе, а &amp;lt;tex&amp;gt; E &amp;lt;/tex&amp;gt; {{---}} количество ребер между ними. Если же вместо кучи использовать дерево ван Эмде Боаса, то релаксация и поиск минимума будут занимать уже не &amp;lt;tex&amp;gt; \log V &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; \log k &amp;lt;/tex&amp;gt;, и итоговая асимптотика этого алгоритма снизится до &amp;lt;tex&amp;gt; O(E \cdot \log k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&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; \Theta(2^k) &amp;lt;/tex&amp;gt; памяти, что несложно доказывается индукцией, учитывая, что &amp;lt;tex&amp;gt; S(2^k)=(2^{k/2} + 1) \cdot S(2^{k/2}) + O(2^{k/2})&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; S(2^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;
* [[Дерево поиска, наивная реализация|Дерево поиска]]&lt;br /&gt;
* [[Алгоритм Дейкстры]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Van_Emde_Boas_tree Van Emde Boas tree — Wikipedia]&lt;br /&gt;
*[http://habrahabr.ru/post/125499 Дерево ван Эмде Боаса — habrahabr.ru]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Деревья поиска]]&lt;br /&gt;
[[Категория: Структуры данных]]&lt;/div&gt;</summary>
		<author><name>5.18.213.18</name></author>	</entry>

	</feed>