Дерево ван Эмде Боаса — различия между версиями
Warrior (обсуждение | вклад) |
Warrior (обсуждение | вклад) |
||
Строка 7: | Строка 7: | ||
Особенностью этой структуры является то, что все операции выполняются за <tex>O(\log k)</tex>, что асимптотически лучше, чем <tex>O(\log n)</tex> в большинстве других деревьев поиска, где <tex>n</tex> {{---}} количество элементов в дереве. | Особенностью этой структуры является то, что все операции выполняются за <tex>O(\log k)</tex>, что асимптотически лучше, чем <tex>O(\log n)</tex> в большинстве других деревьев поиска, где <tex>n</tex> {{---}} количество элементов в дереве. | ||
− | + | = Структура = | |
Пусть есть множество <tex>m[0 \dots M-1]</tex> мы хотим записать эти данный в дерево. | Пусть есть множество <tex>m[0 \dots M-1]</tex> мы хотим записать эти данный в дерево. | ||
[[Файл:Boas.jpg.jpg|right|380px|thumb|корень дерева]] | [[Файл:Boas.jpg.jpg|right|380px|thumb|корень дерева]] | ||
Строка 22: | Строка 22: | ||
В вспомогательном дереве хранится информация о том, какие клетки уже заняты. То есть значение <tex>i</tex> хранится в вспомогательном дереве только если занят элемент с индексом <tex>i</tex> в массиве детей. | В вспомогательном дереве хранится информация о том, какие клетки уже заняты. То есть значение <tex>i</tex> хранится в вспомогательном дереве только если занят элемент с индексом <tex>i</tex> в массиве детей. | ||
+ | = Операции = | ||
Рассмотрим две опeрации | Рассмотрим две опeрации | ||
Insert(x) | Insert(x) | ||
Delete(T, x) | Delete(T, x) | ||
− | + | == find == | |
− | == | + | == insert == |
Операция добавления элемента <tex>x</tex> - эта задача делится на несколько частей | Операция добавления элемента <tex>x</tex> - эта задача делится на несколько частей | ||
Строка 57: | Строка 58: | ||
</pre> | </pre> | ||
− | == | + | == remove == |
Удаление из дерева T также делится на несколько подзадач: | Удаление из дерева T также делится на несколько подзадач: | ||
*Если T.min = T.max = x, значит в дереве один элемент, мы его удалим и как-нибудь пометим, что дерево пусто(на будущее). | *Если T.min = T.max = x, значит в дереве один элемент, мы его удалим и как-нибудь пометим, что дерево пусто(на будущее). | ||
Строка 94: | Строка 95: | ||
(с)wikipedia.org | (с)wikipedia.org | ||
</pre> | </pre> | ||
+ | == min и max == | ||
+ | |||
+ | == next и prev == | ||
+ | |||
+ | = Источники = | ||
+ | |||
+ | *[http://en.wikipedia.org/wiki/Van_Emde_Boas_tree Van Emde Boas tree — Wikipedia] | ||
+ | *[http://habrahabr.ru/post/125499 Дерево ван Эмде Боаса — habrahabr.ru] |
Версия 21:05, 3 апреля 2012
Определение: |
Дерево ван Эмде Боаса — структура данных, представляющая собой дерево поиска, позволяющее хранить целые неотрицательные числа в интервале | и осуществлять над ними все соответствующие дереву поиска операции.
Проще говоря, данная структура позволяет хранить
-битные числа и производить над ними операции , , , , , , и некоторые другие операции, которые присущи всем деревьям поиска.Особенностью этой структуры является то, что все операции выполняются за
, что асимптотически лучше, чем в большинстве других деревьев поиска, где — количество элементов в дереве.Содержание
Структура
Пусть есть множество
мы хотим записать эти данный в дерево.Будем называть наше дерево
. В корне(root) будут храниться:- массив детей размером (T.children[])
- значение текущего минимума и максимума в дерево (T.min, T.max)
- вспомогательный массив (T.aux)
Элемент массива из детей с индексом
является также деревом для множестваВ вспомогательном дереве хранится информация о том, какие клетки уже заняты. То есть значение
хранится в вспомогательном дереве только если занят элемент с индексом в массиве детей.Операции
Рассмотрим две опeрации Insert(x) Delete(T, x)
find
insert
Операция добавления элемента
- эта задача делится на несколько частей- Если дерево пусто, то меняем значения минимума и максимума на x;
- Если x<T.min тогда мы кладем T.min в поддерево i соответствующее T.min и ставим T.min = x. Если поддерево[i] до этого было пусто то мы также добавляем i в вспомогательное дерево.
Аналогично если x>T.max.
- Если T.min< x < T.max тогда кладем x в поддерево i соответствующее x и меняем вспомогательное дерево.
Insert(T, x) if (T.min > T.max) // T is empty T.min = T.max = x; return if (T.min = T.max) if (x < T.min) T.min = x; if (x > T.max) T.max = x; return if (x < T.min) swap(x, T.min) if (x > T.max) swap(x, T.max) i = x/sqrt(M) Insert(T.children[i], x % sqrt(M)) if (T.children[i].min = T.children[i].max) Insert(T.aux, i) (с)wikipedia.org
remove
Удаление из дерева T также делится на несколько подзадач:
- Если T.min = T.max = x, значит в дереве один элемент, мы его удалим и как-нибудь пометим, что дерево пусто(на будущее).
- Если x = T.min,то мы должны найти следующий второй минимум удалить его из того места где он находится и поставить в T.min Второй минимум - это либо T.max, либо T.children[T.aux.min].min.
Аналогично для случая x = T.max
- Если же x = T.min и x = T.max, то мы должны удалить x из поддерева i отвечающего x.
Важно, что Delete реализован рекурсивно от дерева в котором идет удаления. Так же нельзя забывать, что если мы удаляем последнее вхождение x, то мы должны удалить i из вспомогательного дерева.
Delete(T, x) if (T.min == T.max == x) T.min = M T.max = -1 return if (x == T.min) if (T.aux is empty) T.min = T.max return else x = T.children[T.aux.min].min T.min = x if (x == T.max) if (T.aux is empty) T.max = T.min return else x = T.children[T.aux.max].max T.max = x if (T.aux is empty) return i = floor(x/sqrt(M)) Delete(T.children[i], x%sqrt(M)) if (T.children[i] is empty) Delete(T.aux, i) (с)wikipedia.org