Sequence containers in C++ include: vector, array, list, forward_list, deque. The common operations I look are are:
Initialization
Push front, push back
Sequential Access, random access
Element removal
Slightly more advanced operations are:
Appending one container to another
Resize, reserve
In the meantime, we want to look at the time complexity of each push and removal operations. Each type of container has their unque features as well. We will see them in the following sections.
Vector Operations
1
2
3
vector1.resize(vector1.size()+vector2.size());// - Append `vector2` to the end of `vector1`vector1.insert(vector1.end(),vector2.begin(),vector2.end());
Appending an element to the end of vector can be done by insert(target_it, source_end_it, source_end_it);.
But once vec.capacity() < vector1.size() + vector2.size(), memory reallocation will happen. So the worst case is O(N).
Memory Reallocation Of Vector
vector under the hood is like an array, which uses contiguous memory. Therefore when no contiguous memory is found, the whole vector needs to be moved over
If the data is POD (Plain Old Data) like int, the data will be copied over.
If the data has a move ctor, it will be moved over, otherwise copied.
// 1. list initializationstd::list<int>ls{1,2,3};// 2. forward insert, backward insertls.push_front(0);ls.push_back(1);// 3. Access - No random access, just bi-directional accessfor(constauto&m:ls){cout<<m<<", ";}cout<<endl;ls.push_front(2);ls.push_front(3);// 4. remove 1: erase-remove idiom; O(1)ls.erase(ls.begin());// C++ 11// 4. remove 2: std::erase()std::erase(ls,2);// C++ 20 // 4. remove 3 all occurences of 1, so it's o(n) ls.remove(1);for(auto&m:ls){cout<<m<<endl;// sew 1}
Advanced Operations:
1
2
3
4
5
6
7
8
9
10
11
12
13
list<int>ls{1,2,3};list<int>ls2{1,2,3};// 1. Appending a whole listls.splice(ls.end(),ls2);// 2. Appending a single element: autoit=ls.begin();std::advance(it,1);ls.splice(ls.end(),ls2,it);std::advance(it,1);// std::advance() is a void function// 3. Appening a segment of list:ls.splice(ls.end(),ls2,ls.begin(),it);
appending one container to another: use splice. Splice means “connecting two ropes together through intertwining”.
source list ls2 is always required in std::list::splice. See the above for 3 its 3 usages
This is O(1), because the splice will just manipulate the iterator inside.
Vector Operations
Filling Operations
Fill a vector with 0, 1,2,3,...: std::iota. iota is the greek word for “small amount”