Доступ STL-доступа по индексу равен O (1)?

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

abc- > defghi- > jkl- > MNOP

Элементы deque выше состоят из одного символа. Набор символов в одной группе указывает, что он выделен в непрерывной памяти (например, abc находится в одном блоке памяти, defhi находится в другом блоке памяти и т.д.). Может ли кто-нибудь объяснить, как доступ по индексу позиции может выполняться в постоянное время, особенно если элемент, к которому нужно получить доступ, находится во втором блоке? Или у deque есть указатель на группу блоков?

Обновление: или существует ли другая общая реализация для deque?

Ответ 1

Я нашел эту реализацию deque из Wikipedia:

Сохранение содержимого в нескольких меньших массивах, распределение дополнительных массивов в начале или в конце по мере необходимости. Индексирование осуществляется путем сохранения динамического массива, содержащего указатели, для каждого из меньших массивов.

Я думаю, это отвечает на мой вопрос.

Ответ 2

Одна из возможных реализаций может быть динамическим массивом массивов const-size; такой массив const-size может быть добавлен в любой конец, когда требуется больше места. Все массивы полны, за исключением, возможно, для первого и последнего, которые могут быть частично пустыми. Это означает, что зная размер каждого массива и количество элементов, используемых в первом массиве, можно легко найти позицию элемента по индексу. http://cpp-tip-of-the-day.blogspot.ru/2013/11/how-is-stddeque-implemented.html

Ответ 3

Если deque реализован как кольцевой буфер поверх std::vector, который перераспределяет себя, когда он растет в размере, тогда доступ индекс действительно равен O (1).

В стандарте приводятся доказательства того, что такая реализация подразумевалась - по крайней мере, она соответствует стандартным оценкам сложности. В пунктах 23.2.1.3/4 и 23.2.1.3/5 требуется, чтобы

  • Вставка в начало или до конца дека требует постоянного времени, а вставка в середину требует линейного времени размера deque

  • при стирании элементов из deque он может вызывать столько операторов присваивания, что расстояние от стираемых элементов до конца дека есть.

И, конечно же, вы должны рассчитывать на стандартные требования вместо своего собственного видения того, как можно реализовать контейнеры и алгоритмы.

ПРИМЕЧАНИЕ, что стандарт требует больше, чем эти две точки, перечисленные выше. Он также требует, чтобы ссылки на элементы оставались действительными между вставками в спину или перед деком. Это может быть выполнено, если кольцевой буфер содержит указатели на фактические элементы, а не на сами элементы. В любом случае, мой ответ просто демонстрирует идею о том, что несколько реализаций могут удовлетворять определенным требованиям.