Похоже, что все может быть правдой:
- Ваши ключи - строки.
- Вставки выполняются один раз.
- Поиск часто производится.
- Количество пар ключ-значение относительно мало (скажем, меньше, чем K или около того).
Если это так, вы можете рассмотреть отсортированный список поверх любой из этих других структур. Это будет работать хуже, чем другие во время вставок, поскольку отсортированный список равен O (N) для вставки, в отличие от O (1) для связанного списка или хэш-таблицы, и O (log 2 N) для сбалансированное бинарное дерево. Но поиск в отсортированном списке может быть быстрее, чем любая из этих других структур (я объясню это в ближайшее время), так что вы можете выйти на первое место. Кроме того, если вы выполняете все свои вставки одновременно (или иначе не требует поиска, пока все вставки не завершены), то вы можете упростить вставки до O (1) и сделать одну намного более быструю сортировку в конце. Более того, отсортированный список использует меньше памяти, чем любая из этих других структур, но это может иметь значение только в том случае, если у вас много небольших списков. Если у вас есть один или несколько больших списков, то хеш-таблица, скорее всего, превзойдет отсортированный список.
Почему поиск может быть быстрее с отсортированным списком? Что ж, ясно, что это быстрее, чем связанный список, со временем поиска O (N). В двоичном дереве поиски остаются только O (log 2 N), если дерево остается идеально сбалансированным. Сохранение сбалансированного дерева (например, красно-черного) увеличивает сложность и время вставки. Кроме того, как со связанными списками, так и с двоичными деревьями, каждый элемент представляет собой отдельно выделенный 1 узел , что означает, что вам придется разыменовывать указатели и, вероятно, переходить к потенциально сильно меняющимся адресам памяти , увеличивая шансы на промах кеша.
Что касается хеш-таблиц, вам, вероятно, следует прочитать пару из других вопросов здесь, в StackOverflow, но основные моменты, представляющие интерес:
- В худшем случае хеш-таблица может вырождаться до O (N).
- Стоимость хэширования не равна нулю, и в некоторых реализациях она может быть значительной, особенно в случае строк.
- Как и в связанных списках и двоичных деревьях, каждая запись представляет собой узел , хранящий больше, чем просто ключ и значение, также выделенные отдельно в некоторых реализациях, поэтому вы используете больше памяти и увеличиваете вероятность пропадания кэша .
Конечно, если вы действительно заботитесь о том, как будет работать любая из этих структур данных, вам следует проверить их. У вас не должно возникнуть проблем с поиском хороших реализаций любого из них для большинства распространенных языков. Не должно быть слишком сложно бросить некоторые из ваших реальных данных в каждую из этих структур данных и посмотреть, какие из них работают лучше всего.
- Реализация может предварительно выделить массив узлов, что поможет решить проблему с отсутствием кэша. Я не видел этого ни в одной реальной реализации связанных списков или бинарных деревьев (конечно, я не видел каждый из них), хотя вы, конечно, могли бы свернуть свои собственные. У вас все равно будет немного более высокая вероятность пропадания кэша, поскольку объекты node обязательно будут больше, чем пары ключ / значение.