Ваши точные требования не могут быть выполнены: std::unordered_map
работает быстро (т. е. O(1)
вставка/удаление/поиск), потому что не упорядочивает свои элементы. Это означает, что поиск минимума/максимума занимает O(N)
.
Цена заказа, уплаченная std::map
за то, что вставка/удаление/поиск (включая нахождение минимума/максимума) становится O(log N)
.
Если вы не возражаете против использования Boost, вы можете взглянуть на Boost.MultiIndex. Это позволяет вам получать доступ к вашим данным через несколько интерфейсов одновременно. Это чрезвычайно универсальная и высокопроизводительная библиотека, которую также можно использовать для структур данных кэша MRU (которые также сочетают в себе быстрый доступ и отслеживание порядка).
Ваш основной интерфейс std::unordered_map
предоставляется индексом hashed_unique
, где вы используете объект функции identity
(предоставляемый Boost.MultiIndex). Ваш вторичный интерфейс будет имитировать std::set
. Это позволяет найти минимальное/максимальное значение в O(1)
времени как *begin()
и *rbegin()
.
Вы можете сделать это, добавив индекс ordered_unique
с определяемым пользователем функциональным объектом MyOrder
для вычисления любого критерия, который вы хотите использовать для их упорядочения. Небольшой пример кода (исключая пространство имен boost::
везде)
using MyContainer = multi_index_container<
Item,
indexed_by<
hashed_unique<identity<Item>>, // O(1) erasure/lookup, O(log N) insertion
ordered_unique<MyOrder<Item>> // track minimum/maximum in O(log N)
>
>;
За кулисами Boost.MultiIndex реализует это примерно как std::set<Value>
с std::unordered_map<Key, set<Value>::iterator>
. Это означает, что и поиск, и стирание O(1)
. Стирание может быть O(1)
, потому что unordered_map::erase(value)
возвращает итератор в set
, а std::set<Value>::erase(iterator)
равно O(1)
.
Однако количество вставок остается O(log N)
, потому что вы не можете избежать поиска ранга вновь вставленного значения в упорядоченной последовательности за меньшее время.
Это улучшение по сравнению с std::map
для поиска/стирания стоит всего несколько указателей на элементное пространство.
person
TemplateRex
schedule
22.01.2014
std::map
). Обратите внимание, что ваш поиск unordered_map по-прежнему будет таким же быстрым... просто ваша вставка и стирание замедлятся до уровня производительности двоичного дерева. - person Tony Delroy   schedule 22.01.2014std::unordered_map
? - person Bryan Chen   schedule 22.01.2014std::unordered_map
быстрый - person Oleg Vazhnev   schedule 22.01.2014std::map
илиboost::container::flat_map
(boost.org/doc/libs/1_55_0/doc/html/container/)? Насколько часты вставки по сравнению с удалениями? Если вставки происходят намного чаще, чем вставки, то увеличение минимального/максимального значения при вставке, но отмена его действия при удалении, возможно, может быть вариантом. - person dalle   schedule 22.01.2014