Ответ 1
Все немного отличается для std::vector
и std::deque
, а также для С++ 98 и С++ 11.
std::vector
Сложность std::vector::erase()
является линейной как по длине стираемого диапазона, так и по количеству элементов между концом диапазона и концом контейнера (поэтому стирание элемента с конца занимает постоянное время).
С++ 2003 [lib.vector.modifiers]
читает:
iterator erase(iterator position);
iterator erase(iterator first, iterator last);`
...
Сложность: деструктор
T
называется числом раз, равным числу стираемых элементов, но оператор присваиванияT
называется числом раз, равным числу элементов в векторе после стираемых элементов.
С++ 14 черновик N4140 [vector.modifiers]
читает:
Сложность: деструктор
T
называется числом раз, равным числу элементов стирается, но оператор присваивания перемещенияT
называется числом раз, равным числу элементов в векторе после стираемых элементов.
Итак, вы видите, что реализация С++ 11/14 более эффективна, поскольку она выполняет назначение переноса вместо назначения копии, но сложность остается прежней.
станд:: Deque
Сложность std::deque::erase()
является линейной как по длине стираемого диапазона, так и по минимуму двух чисел: количеству оставшихся элементов до начала диапазона и количеству оставшихся элементов после окончания диапазона. Итак, стирание элемента либо с начала, либо с конца занимает постоянное время.
С++ 2003 [lib.deque.modifiers]
:
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
Сложность: количество вызовов деструктора совпадает с количеством стираемых элементов, но число вызовов оператора присваивания максимально равно минимальному числу элементов перед стираемыми элементами и количеством элементов после стираемых элементов.
С++ 14 черновик N4140 [deque.modifiers]/5
:
Сложность: количество вызовов деструктора совпадает с количеством стираемых элементов, но количество вызовов оператора присваивания не больше, чем меньшее количество элементов перед стираемыми элементами и количество элементы после стираемых элементов.
Итак, это то же самое в С++ 98 и С++ 11/14, опять же за исключением того, что С++ 11 может выбирать между назначением перемещения и присваиванием копии (здесь я вижу некоторую несогласованность в стандарте, поскольку формулировка doesn ' t упоминание переадресации как для std::vector
- может быть причиной для другого вопроса).
Обратите внимание также на "самое большее" и "не больше" в формулировках. Это позволяет реализациям быть более эффективными, чем линейные, хотя на практике они линейны (DEMO).