Предыдущие ответы только альтернативы адресного дерева, и красный черный, вероятно, остается только по историческим причинам.
Почему бы не хеш-таблица?
Для типа требуется только сравнение <
для использования в качестве ключа в дереве.Однако для хеш-таблиц требуется, чтобы для каждого типа ключа была определена функция hash
.Соблюдение минимальных требований к типу очень важно для общего программирования.
Разработка хорошей хеш-таблицы требует глубокого знания контекста, в котором она будет использоваться.Должен ли он использовать открытую адресацию или связанную цепочку?Какие уровни нагрузки следует принять перед изменением размера?Следует ли использовать дорогой хеш, который избегает столкновений, или грубый и быстрый?
Поскольку STL не может предвидеть, какой вариант является наилучшим для вашего приложения, по умолчанию он должен быть более гибким.Деревья «просто работают» и хорошо масштабируются.
(C ++ 11 добавил хеш-таблицы с unordered_map
. Как видно из документации , для настройки многих из них требуется настройка политикварианты.)
А как насчет других деревьев?
Red Black предлагает быстрый поиск и самобалансировку, в отличие от BST.Другой пользователь указал на свои преимущества перед самобалансирующимся деревом AVL.
Александр Степанов (создатель STL) сказал, что он будет использовать дерево B * вместо красно-черного дерева, если он снова напишет std::map
, потому что оно более дружественно для современных кэшей памяти.
Одним из самых больших изменений с тех пор стал рост кешей.Промахи в кеше очень дороги, так что местность ссылок сейчас гораздо важнее.Структуры данных на основе узлов, которые имеют низкую локальность ссылок, имеют гораздо меньше смысла.Если бы я проектировал STL сегодня, у меня был бы другой набор контейнеров.Например, B * -дерево в памяти - гораздо лучший выбор, чем красно-черное дерево для реализации ассоциативного контейнера.- Александр Степанов
Следует ли вам всегда использовать красное черное дерево или дерево B *?
В других случаях Алекс заявлял, чтоstd::vector
почти всегда является лучшим контейнером списка по аналогичным причинам.Редко имеет смысл использовать std::list
или std::deque
даже для тех ситуаций, которым нас учили в школе (таких как удаление элемента из середины списка).std::vector
настолько быстр, что превосходит эти структуры для всего, кроме большого N
.
Применяя эту аргументацию, если у вас есть только небольшое количество элементов (сотни?), Используя std::vector
и линейный поиск может быть более эффективным, чем реализация дерева std::map
.В зависимости от частоты вставки сортировка std::vector
в сочетании с std::binary_search
может быть самым быстрым выбором.