I have read that time complexity of adding items to end of a std::vector
is amortized constant and inserting items at the top and bottom of a std::deque
is constant.Since both these containers have a random access iterator thus accessing elements at any index is constant. Please let me know if I have any of these facts wrong.My question is if accessing an element in a std::vector
or std::deque
is constant then why is the time complexity of removing an element via erase O(n). One of the answers here here states that removing elements via erase is O(n). I know that erase removes the elements between the starting iterators and the ending one so does the answer basically mean that its O(n)
depending on the no of elements between the two iterators and that removing a single element from a vector/deque in any index will be zero?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
- What is the correct way to declare and use a FILE
Removing elements is indeed
O(n)
not because of what you have to do to find the element to remove but because of what you have to do to all of the ones after it. Those elements need to be slid down to fill the empty slot.So on average, erase will take an element about halfway through the vector, so you'll have to shift about half the elements. Hence
O(n)
. Best case, you erase the last element - no sliding necessary. Worst case, you erase the first element - have to then move every other element.Erasing an element in a vector is O(n) since once you remove the element you still need to shift all successive elements to fill the gap created. If a vector has n elements, then at the worst case you will need to shift n-1 elemets, hence the complexity is O(n).
The things are a bit different for
std::vector
andstd::deque
, as well as they are different for C++98 and C++11.std::vector
The complexity of
std::vector::erase()
is linear both to the length of the range erased and to the number of elements between the end of the range and the end of the container (so erasing an element from the end takes constant time).C++2003
[lib.vector.modifiers]
reads:C++14 draft N4140
[vector.modifiers]
reads:So you see that C++11/14 implementation is more efficient in general since it perform move assignment instead of copy assignment, but the complexity remains the same.
std::deque
The complexity of
std::deque::erase()
is linear both to the length of the range erased and to the minimum of two numbers: number of remaining elements before the start of the range, and number of remaining elements after the end of the range. So, erasing an element either from the beginning or from the end takes constant time.C++2003
[lib.deque.modifiers]
:C++14 draft N4140
[deque.modifiers]/5
:So, it's the same in C++98 and C++11/14, again except that C++11 can choose between move assignment and copy assignment (here I see some inconsistency in the standard because the wording doesn't mention move assignment like for
std::vector
- might be a reason for another question).Note also the "at most" and "no more" in the wordings. This allows for implementations to be more efficient than linear, though in practice they are linear (DEMO).