Существует ли конкретная структура данных, которую должна реализовывать двухсторонняя очередь в C ++ STL, или же двухсторонняя очередь представляет собой лишь расплывчатое представление о массиве, растущем как спереди, так и сзади, которое должно быть реализовано независимо от реализации?
Раньше я всегда предполагал, что двухсторонняя очередь - это кольцевой буфер , но недавно я читал ссылку на C ++ здесь , и похоже, что двухсторонняя очередь - это своего рода массив массивов. Не похоже, что это простой старый кольцевой буфер. Значит, это буфер пробелов или какой-то другой вариант расширяемого массива , или он просто зависит от реализации?
ОБНОВЛЕНИЕ И РЕЗЮМЕ ОТВЕТОВ :
Похоже, что общее мнение таково, что двухсторонняя очередь - это такая структура данных, что:
Кажется, никто не знает, как получить комбинацию 1-го и 4-го условий, если мы примем первое условие как «неамортизированное постоянное время». Связанный список достигает 1), но не 4), тогда как типичный кольцевой буфер достигает 4), но не 1). Я думаю, что у меня есть реализация, которая удовлетворяет обоим нижеприведенным. Комментарии?
Мы начинаем с реализации, которую предложил кто-то другой: мы выделяем массив и начинаем размещать элементы с середины, оставляя пространство как спереди, так и сзади. В этой реализации мы отслеживаем, сколько элементов находится от центра как в переднем, так и в обратном направлениях, называем эти значения F и B. Затем давайте дополним эту структуру данных вспомогательным массивом, который в два раза превышает размер оригинала. array (теперь мы тратим кучу места, но не меняем асимптотическую сложность).Мы также заполним этот вспомогательный массив от его середины и присвоим ему аналогичные значения F 'и B'. Стратегия такова: каждый раз, когда мы добавляем один элемент в первичный массив в заданном направлении, если F> F 'или B> B' (в зависимости от направления), до двух значений копируются из первичный массив во вспомогательный, пока F 'не догонит F (или B' с B). Таким образом, операция вставки включает в себя размещение 1 элемента в первичном массиве и копирование до 2 элементов из первичного во вспомогательный, но это по-прежнему O (1). Когда первичный массив заполняется, мы освобождаем первичный массив, делаем вспомогательный массив первичным массивом и делаем другой вспомогательный массив, который еще в 2 раза больше. Этот новый вспомогательный массив начинается с F '= B' = 0 и в него ничего не копируется (поэтому операция изменения размера равна O (1), если распределение кучи составляет O (1) сложность). Поскольку вспомогательные копируют 2 элемента для каждого элемента, добавленного к первичному, а первичный начинается максимум наполовину, для вспомогательного невозможно не догнать первичный к тому времени, когда первичный элемент снова исчерпает пространство. При удалении также нужно удалить 1 элемент из основного и 0 или 1 из вспомогательного. Итак, предполагая, что выделение кучи равно O (1), эта реализация удовлетворяет условию 1). Мы делаем массив из T * и используем new
при вставке, чтобы выполнить условия 2) и 3). Наконец, 4) выполняется, потому что мы используем структуру массива и можем легко реализовать доступ O (1).