Конкретные примеры использования бинарных деревьев поиска?

Я понимаю, как реализуются деревья двоичного поиска, но я не уверен, каковы преимущества его использования по сравнению с хэш-таблицами, которые большинство языков программирования встроили в свои стандартные библиотеки.

может ли кто-нибудь привести примеры реальных проблем, разрешимых с помощью бинарных деревьев поиска?

5 ответов


есть несколько теоретических преимуществ деревьев двоичного поиска над хэш-таблицами:

  1. они хранят свои элементы в отсортированном порядке. Это означает, что если вы хотите сохранить контейнер таким образом, чтобы вы могли легко посетить значения в отсортированном порядке, BST, вероятно, лучший выбор, чем хэш-таблица. Например, если вы хотите сохранить коллекцию студентов, а затем распечатать всех студентов в алфавитном порядке, BST является существенным лучший выбор, чем хэш-таблица.

  2. они эффективно поддерживают запросы диапазона. поскольку BSTs хранятся в отсортированном порядке, легко ответить на вопросы формы "какие значения находятся в диапазоне [x, y]?- в двоичном дереве поиска. Чтобы сделать это, выполните поиск в дереве для наименьшего элемента больше x и наибольшего элемента меньше y, а затем повторите элементы дерева между ними. Оба этих запроса выполняются в O (lg n) раз в a сбалансированное дерево, поэтому общее время выполнения для этой операции-O (lg n + k), где k-количество элементов, соответствующих запросу.

  3. они эффективно поддерживают запросы ближайшего соседа. хэш-таблицы специально разработаны так, что даже немного разные производят дико разные хэш-коды. Это дает хэш-значениям дисперсию, необходимую им, чтобы избежать кластеризации слишком много элементов в одном месте. Однако это также означает, что вам нужно выполнить линейное сканирование хэш-таблица для поиска элементов, которые могут быть "близки" к тому, что вы ищете. С помощью BST вы можете эффективно найти предшественника и преемника любой ценности, даже если он не находится в дереве.

  4. они могут иметь лучшие гарантии наихудшего случая. большинство реализаций хэш-таблицы имеют какой-то вырожденный случай, в котором операция может деградировать до O(n) в худшем случае. Линейная зондирующая хэш-таблица или цепная хэш-таблица могут с плохим набором элементов, требуют O(n) времени на поиск или требуют O (n) времени на повторный хэш. Вставка в некоторые типы сбалансированных BSTs, такие как красные/черные деревья, деревья AVL или деревья AA, всегда в худшем случае O(lg n).

Если вы хотите обобщить BSTs на более сложные древовидные структуры, то есть много приложений, в которых дерево может использоваться для решения проблем гораздо эффективнее, чем в хэш-таблице. Вот несколько примеры:

  1. KD-деревьев позволяет хранить многомерные данные, поддерживая запросы быстрого диапазона в многомерном пространстве, а также эффективные поиски ближайшего соседа. Вы можете использовать их для классификации (ленивые алгоритмы обучения) или вычислительной геометрии.

  2. ссылка/вырезать деревья может использоваться для решения задач с максимальным потоком намного эффективнее, чем большинство обычных алгоритмов. Хороший алгоритмы push/relabel используют это для ускорения своих реализаций.

  3. непересекающихся-установка лесов может использоваться для поддержания разбиений элементов как можно более асимптотически эффективно (амортизированный α(n) на обновление, где α(n) - обратная функция Аккермана). Они используются во многих быстрых алгоритмах с минимальным охватом дерева, а также в некоторых алгоритмах максимального соответствия.

  4. двоичные кучи может использоваться для реализации очереди приоритетов эффективно. Более сложные деревья можно использовать для построения биномиальные кучи и кучи Фибоначчи, которые имеют большое значение в теоретической информатике.

  5. деревья решений может использоваться в машинном обучении для классификации и в качестве модели в теоретической информатике для доказательства границ времени выполнения различных алгоритмов.

  6. троичные деревья поиска - это альтернатива попыткам, которые основаны на слегка измененном BST. Они позволяют очень быстро искать и вставлять элементы, а для разреженных наборов данных довольно лаконичны.

  7. B-деревьев используются многими системами баз данных для эффективного поиска элементов, где доступ к диску является ограничивающим фактором.

  8. деревья разбиения двоичного пространства являются обобщением KD-деревьев, которые могут быть использованы для быстрого отображения компьютерной графики (они использовались для оптимизации рендеринга в оригинальной игре Doom)и обнаружения столкновений.

  9. BK-деревья позволяет быстро определить все слова, которые находятся в пределах определенного расстояния редактирования какого-либо другого слова, и в более общем плане найти все точки в метрическом пространстве на определенном расстоянии от какой-либо другой точки.

  10. слияние деревьев являются альтернативой хэш-таблицам для целых ключей, которые имеют чрезвычайно быструю поддержку для поиска, вставки и удаления.

  11. Ван Сфррс Боаш деревьев другая альтернатива хэш-таблицам для целочисленных ключей, поддерживающих поиск, вставку, удаление, преемник и предшественник в O(lg lg n) время на элемент. Некоторые системы баз данных используют деревья vEB для оптимизации производительности.

Я не уверен, как по теме этот ответ, но он должен дать вам представление о том, насколько замечательные и мощные BSTs и более общие древовидные структуры может быть.


одним из примеров того, где требуется двоичное дерево, являются разделы двоичного пространства в компьютерной графике

http://en.wikipedia.org/wiki/Binary_space_partitioning

двоичное дерево необходимо, потому что алгоритм требует сохранения отношений между узлами в двоичном дереве. Существует много других алгоритмов, где важна структура дерева, и поэтому хэш-таблица не является подходящей структурой.

другой хорошей причиной использования двоичного дерева вместо хэш-таблицы является то, что вы не можете легко создать эффективный хэш для своих элементов данных, но вы можете создать функцию сравнения.

часто для простого хранения и извлечения данных хэш-таблица является более оптимальной, но более сложной для реализации.


одним из самых упущенных является то, что многие файловые системы используют двоичные деревья для управления списками каталогов. Они редко используют простое двоичное дерево, но некоторые варианты, такие как B-дерево. Это связано с тем, что вопрос о хранении дерева на диске довольно важен для деталей реализации. Причина, по которой они используют такую структуру, заключается в эффективности и скорости. Это позволяет им делать такие вещи, как поддержка тысяч файлов в каталоге. Сравнение времени создания и удаления файлов выделите эффективность для этого аспекта файловой системы.

двоичные деревья также используются во многих играх, которые отображают 3D-объекты. Опять же, причина в скорости. На самом деле скорость настолько важна, что некоторые игровые движки, такие как Quake engine, фактически имеют двоичное дерево, предварительно сгенерированное и оптимизированное как часть процесса построения карты.


следует отметить, что двоичное дерево поиска эффективно для пространства. Например, у вас есть 10 целых чисел для хранения, и у вас есть хэш - функция, которая отображает от 0 до 99, тогда вам нужен массив из 100 целых чисел. Если вы использовали двоичное дерево поиска, то вы выделили бы только столько памяти, сколько требуется 10 элементам


вероятно, это должен быть комментарий, но самобалансирующиеся BST(s) (log (n)) широко используются, а не BSTs. Простые BSTs имеют наихудшее время вставки/удаления O(N).