Как выбрать между хеш-таблицей и Trie (префиксным деревом)? - PullRequest
126 голосов
/ 29 октября 2008

Так что, если мне придется выбирать между хеш-таблицей или деревом префиксов, каковы различающие факторы, которые заставят меня выбрать один из других? С моей наивной точки зрения кажется, что использование trie имеет некоторые дополнительные издержки, поскольку оно не сохраняется в виде массива, но что с точки зрения времени выполнения (при условии, что самый длинный ключ - самое длинное английское слово), это может быть по существу (1) (относительно верхней границы). Может быть, самое длинное английское слово состоит из 50 символов?

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

Может ли кто-нибудь дать мне более опытный взгляд на это? Спасибо!

Ответы [ 8 ]

112 голосов
/ 29 октября 2008

Преимущества попыток:

Основы:

  • Предсказуемое время поиска O (k), где k - размер ключа
  • Поиск может занять меньше k времени, если его там нет
  • Поддержка упорядоченного обхода
  • Нет необходимости в хэш-функции
  • Удаление просто

Новые операции:

  • Вы можете быстро искать префиксы ключей, перечислять все записи с заданным префиксом и т. Д.

Преимущества связанной структуры:

  • Если существует много общих префиксов, то пространство, которое им требуется, используется совместно.
  • Неизменные попытки могут разделить структуру. Вместо того, чтобы обновить дерево на месте, вы можете создать новый, отличающийся только на одной ветви, в другом месте, указывая на старое дерево. Это может быть полезно для параллелизма, нескольких одновременных версий таблицы и т. Д.
  • Неизменяемое дерево сжимаемо. Таким образом, он может разделять структуру на суффиксы также с помощью хеширования.

Преимущества хеш-таблиц:

  • Все знают хеш-таблицы, верно? Ваша система уже будет иметь хорошую, хорошо оптимизированную реализацию, более быструю, чем попытки для большинства целей.
  • Ваши ключи не должны иметь какой-либо специальной структуры.
  • Более компактно, чем очевидная связанная структура дерева ( см. Комментарии ниже )
45 голосов
/ 29 октября 2008

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

24 голосов
/ 15 апреля 2012

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

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

Очень хорошим примером, когда Trie лучше соответствует требованиям, является промежуточное программное обеспечение для обмена сообщениями. У вас есть миллион подписчиков и издателей сообщений различных категорий (в терминах JMS - темы или обмены), в таких случаях, если вы хотите отфильтровать сообщения по темам (которые на самом деле являются строками), вам определенно не нужно создавать хеш-таблицу за миллион подписок с миллионами тем. Лучшим подходом является сохранение тем в три файла, поэтому, когда фильтрация выполняется на основе совпадения тем, ее сложность не зависит от количества тем / подписок / издателей (зависит только от длины строки). Мне это нравится, потому что вы можете проявить творческий подход к этой структуре данных, чтобы оптимизировать требования к пространству и, следовательно, снизить кэш-память.

8 голосов
/ 12 января 2012

Используйте дерево:

  1. Если вам нужна функция автозаполнения
  2. Найти все слова, начинающиеся с 'a' или 'ax' и т. Д.
  3. Дерево суффиксов - это особая форма дерева. Суффикс-деревья имеют целый ряд преимуществ, которые хеш не может охватить.
2 голосов
/ 18 июня 2017

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

P.S .: Кроме них, Trenary Search Trees (TSTs) будет отличным выбором. Его время поиска больше, чем у HashTable, но экономит время во всех других операциях. Кроме того, это более экономно, чем пытается.

1 голос
/ 19 ноября 2017

Вставка и поиск по дереву линейны с длиной входной строки O (s).

Хеш даст вам O (1) для поиска и вставки, но сначала вы должны вычислить хеш на основе входной строки, которая снова равна O (s).

Заключение, асимптотическая сложность по времени линейна в обоих случаях.

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

Чтобы разорвать связь, задайте себе вопрос: мне нужно искать только полные слова? Или мне нужно вернуть все слова, соответствующие префиксу? (Как и в системе интеллектуального ввода текста). Для первого случая перейдите к хешу. Это более простой и понятный код. Проще протестировать и поддерживать. Для более продуманного варианта использования, где префиксы или суффиксы имеют значение, попробуйте три.

И если вы сделаете это просто для удовольствия, реализация трие будет полезным для воскресного дня.

1 голос
/ 16 октября 2014

Есть кое-что, что я не видел, чтобы кто-то прямо упоминал, и я думаю, что это важно иметь в виду. Как в хэш-таблицах, так и в попытках различных типов обычно используются операции O(k), где k - длина строки в битах (или эквивалентно в символах).

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

0 голосов
/ 29 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...