STL - Vectors
cpp
stl
containers
CPP Reference: vector
Present inside the <vector>
header, vectors are dynamic arrays with the ability to resize itself automatically when an element is inserted or deleted
Operation | Time |
---|---|
Element Access | O(1) always |
Insertion | Insertion at the end is O(1) on average but O(N) when resizing Insertion at the start or middle is O(N) |
Deletion | Deletion from the end is O(1) Deletion at the start or middle is O(N) |
Declaration: vector<Type> v1;
Iterators
- Forward:
.begin()
,.end()
- Reverse:
.rbegin()
,.rend()
Element access
[idx]
- Returns reference to element at indexidx
inside the vector..front()
– Returns reference to first element in the vector.back()
– Returns reference to last element in the vector
Size functions
.empty()
- Returns whether the vector is empty or not.size()
- Returns number of elements present inside the vector.capacity()
- Returns number of elements worth of memory currently allocated to the vector.max_size()
- Returns the theoretical maximum number of items that could be put in your vector.resize(n, val)
- Resizes vector to only include firstn
elements. Can also pass extra argumentval
to which the new elements will be initialized
Modifiers
.pop_back()
- Removes last element from the vector. TakesO(1)
time.push_back(val)
- Appends one element having valueval
at the end of element. TakesO(1)
time in most cases ,butO(N)
when resizing.emplace_back(val)
- Constructs the element in-place at the end of the vector. Same time complexity aspush_back()
but one less copy operation.clear()
- Remove all elements. TakesO(N)
time.erase()
- Removes element(s) at specific position viaerase(pos)
or within a range viaerase(start, end)
. TakesO(N)
time on average
Difference between
.emplace_back()
and.push_back()
- Generally,
emplace_back()
is slightly faster thanpush_back()
as it constructs the element in-place whilepush_back()
creates the element and then copies it. So, preferemplace_back()
for complex objects or fast insertion. - You can also pass the appropriate list of arguments to construct the vector element during
emplace_back()
, but forpush_back()
, you need to create the object first.
Ways to initialize a vector
1. Declare and .push_back()
each element:
2. Specify size
and value
(all elements will have same value):
3. List-initialization:
4. From another array or vector via (start_pos, end_pos)
:
5. Using fill()
or fill_n()
to set values:
6. Using iota()
to set values as increments:
Initialising 2D vector
Above line initializes a 2D matrix mat
of 3
rows and 4
columns with the default value -1
at each cell
Traversal
- Range-based loop:
for(auto &element : v1)
- Using iterators:
for(auto itr = v1.begin(); itr != v1.end(); itr++)
- Reverse traversal:
for(auto itr = v1.rbegin(); itr != v1.rend(); itr++)
Traversals demo
More functions:
-
.insert()
: Inserts element(s) at specific postition. TakesO(N)
time on average.insert(pos,val)
: Inserts elementval
at positionpos
.insert(pos,reps,val)
: Insertsreps
number of copies ofval
starting from positionpos
.insert(pos,start,end)
: Inserts all elements of[start, end)
at positionpos
-
.emplace(pos,...args)
- Inserts a new element into the container directly beforepos
by constructing it in-place.
Beware of vector<bool>
vector<bool>
in C++ is a specialization of the standard vector
container class that allows you to store a sequence of boolean values. Unlike a regular vector<T>
where T
can be any data type, vector<bool>
doesn’t store each bool
value as a full byte in memory. Instead, it utilizes bit manipulation techniques to pack multiple boolean values (typically 8) into a single byte. Due to the bit-packing optimization, operations like element access and modification are not as straightforward as with other types:
- No Direct Element Access: You cannot directly access individual elements via
[]
. Instead, you need to use member functions likeat()
or iterators. - No References: The reference type returned by
std::vector<bool>::operator[]
is a proxy class (often calledstd::vector<bool>::reference
), which behaves like abool&
but is not actually a reference to a single bool value. This can lead to confusion and unexpected behavior. You cannot take the address of a bool element in astd::vector<bool>
, as each element is not stored as a separate byte in memory.
Better alternatives:
- If the size is known at compile-time: use
bistset<N>
as suggested by CPP Reference - For dynamic sizes: you can use
vector<char>
orboost::dynamic_bitset