Добавление (или удаление) в начало (или конец) контейнера std::vector
сразу многих объектов может повлечь выполнение большого количества операций выделения памяти для получения пространства, а также потенциально затратных операций по перемещению объектов. В таких ситуациях стоит воспользоваться контейнером std::deque
(deque («дек») расшифровывается как
Хранение списков
Контейнер std::list
представляет собой классический двухсвязный список. Ни больше ни меньше. Если вам нужно выполнять обход списка только в одном направлении, то больше подойдет контейнер std::forward_list
— он быстрее работает и занимает меньше места, поскольку в нем хранятся лишь указатели на следующий элемент. Пройти список можно только последовательно, за время
Деревья поиска
Если для объектов характерен естественный порядок, такой, что их можно отсортировать с использованием математического отношения <
, то их можно поддерживать в этом же порядке с помощью
В STL есть несколько видов таких деревьев, самым простым является std::set
— в нем хранятся
Контейнер std::map
отличается тем, что данные в нем хранятся std::map
в качестве std::set
, все ключи в дереве должны быть в единственном экземпляре.
Контейнеры std::multiset
и std::multimap
являются частными случаями контейнеров, показанных выше, для которых отсутствует требование
Хеш-таблицы
Деревья поиска не единственный способ реализации ассоциативных контейнеров. В
Контейнеры std::unordered_set
и std::unordered_map
весьма похожи на std::set
и std::map
, что можно утверждать на основании их взаимозаменяемости.
Как и реализации поисковых деревьев, у обоих контейнеров есть «коллеги» std::unordered_multiset
и std::unordered_multimap
, которые не имеют ограничения на уникальность объектов/ключей, поэтому можно хранить несколько элементов для одного ключа.
Адаптеры контейнеров
Массивы, списки, деревья и хеш-таблицы не единственный способ хранения данных и получения к ним доступа. Еще есть стеки, очереди и т.д. Аналогично тому, как более сложные структуры могут быть реализованы с использованием более примитивных, в STL такие структуры создаются благодаря следующим классам — std::stack
, std::queue
и std::priority_queue
.
Приятная новость: если нам нужна подобная структура данных, можно просто выбрать адаптер. Далее, понимая, что нас не устраивает производительность, мы можем просто изменить параметр шаблона, чтобы адаптер выбрал другую реализацию контейнера. На практике это значит, например, возможность замены находящейся в основе экземпляра std::stack
реализации с std::vector
на std::deque
.
Используем идиому erase-remove для контейнера std::vector
Многие программисты-новички узнают о существовании класса std::vector
, который в основном работает как