Amortized constant complexity for insertion at the front is (typically) achieved by assigning from the middle of the vector of pointers outwards.
For example, if we have a deque with 3 nodes, each holding up to 4 elements, we might assign its vector of 8 pointers thus:
[ nil, nil, nil, N1*, N2*, N3*, nil, nil ]
Here N1
and N3
might themselves be partially filled:
N1: [ nil, nil, nil, 1 ]
N2: [ 2, 3, 4, 5 ]
N3: [ 6, 7, nil, nil ]
As we push_front
onto the deque, first N1
is filled towards the front, then additional nodes are allocated and added to the vector of pointers. Once the vector of pointers is filled at the front, any additional push_front
results in an exponential expansion with the additional space assigned at the front:
[ N1*, N2*, N3*, N4*, N5*, N6*, nil, nil ]
| `---------------------------------------\
`-----------------------------------v v
[ nil, nil, nil, nil, nil, nil, nil, N0*, N1*, N2*, N3*, N4*, N5*, N6*, nil, nil ]
This exponential growth policy achieves O(1) amortized complexity for both deque::push_front
and deque::push_back
for the same reason that vector::push_back
has O(1) amortized complexity.