In C++, list container implements a doubly linked list in which each element contains the address of next and previous element in the list. It stores data in non-contiguous memory, hence providing fast insertion and deletion once the position of the element is known.
Syntax
A list is defined as the std::list class template inside the <list> header file.
list<T> l;
where,
- T: Type of elements in the list.
- l: Name assigned to the list.
Declaration and Initialization
In C++, list can be declared and initialized in multiple ways as shown in the below example:
C++
#include <iostream>
#include<list>
using namespace std;
void printL(list<int>& l) {
for (auto i : l)
cout << i << " ";
cout << '\n';
}
int main() {
// Creating an empty list
list<int> l1;
// Creating list from initializer list
list<int> l2 = {1, 3, 4, 2, 5};
// Creating list with given size and
// initial value
list<int> l3(5, 9);
printL(l1);
printL(l2);
printL(l3);
return 0;
}
Output1 3 4 2 5
9 9 9 9 9
Basic Operations
The basic operations of list are shown below:
1. Inserting Elements
Fast insertion can be done in a list using insert() function if the iterator to the desired position is known. If not, we have to go through all the element from the beginning or end of the list to the position where we want to insert.
Insertion at beginning or end can be done by push_front() and push_back() respectively.
Example:
C++
#include <iostream>
#include<list>
using namespace std;
int main() {
list<int> l = {3, 2};
// Inserting an element at the end
l.push_back(5);
// Inserting an element at the beginning
l.push_front(1);
// Inserting an element at a specific position
auto it = l.begin();
advance(it, 2);
l.insert(it, 4);
for (auto i : l)
cout << i << " ";
return 0;
}
2. Accessing Elements
Unlike vectors, lists do not support random access. To access any element at a given position, go through the list sequentially from the start or the end to the desired position. However, first and last elements can be quickly accessed using front() and back() methods respectively.
Example:
C++
#include <iostream>
#include<list>
using namespace std;
int main() {
list<int> l = {1, 3, 4, 2, 5};
// Accessing first and last elements
cout << l.front() << endl;
cout << l.back() << endl;
// Access third element
cout << *next(l.begin(), 2);
return 0;
}
Explanation: In this program, we print first element and last element of the list l using front()and back()method. To access the thirdelement, next() function is used to move the begin() iteratortwo positions forward retrieves the value4.
3. Updating Elements
List elements can be updated by assigning the desired value using assignment operators while accessing the elements.
Example:
C++
#include <iostream>
#include<list>
using namespace std;
int main() {
list<int> l = {1, 3, 4, 2, 5};
// Changing the first element
l.front() = 11;
// Move iterator to the second element
auto it = l.begin();
advance(it, 2);
// Update the value using iterator
*it = 10;
for (auto i : l)
cout << i << " ";
return 0;
}
Explanation:In this program, the first element is modified using the reference returned by the front()
function. To modify the third element, the iterator to the first element is moved 2 positions forward using the advance()
function. Then, the value is updated by dereferencing the iterator.
4. Finding Elements
To find any particular element in the list, the find() function from algorithm library can be used.
Example:
C++
#include <iostream>
#include<list>
using namespace std;
int main() {
list<int> l = {1, 3, 4, 2, 5};
// Finding 4
auto it = find(l.begin(), l.end(), 4);
if (it != l.end()) cout << *it;
else cout << "Element Not Found!";
return 0;
}
Explanation: In this example, the find() function searches for the element 4 in the list l. If found, it returns an iterator pointing to the element, which is dereferenced and printed, otherwise, it returns end() iterator.
5. Traversing
A list can be easily traversed using begin() and end() iterators with any loop. Just move the begin() iterator till it is not equal to the end() iterator and access elements in each iteration.
Example:
C++
#include <iostream>
#include<list>
using namespace std;
int main() {
list<int> l = {1, 3, 4, 2, 5};
// Traversing using iterators
for (auto it = l.begin(); it != l.end(); ++it)
cout << *it << " ";
return 0;
}
Other method to traverse is to use the range based for loop like we have done in previous examples.
6. Deleting Elements
The erase()can delete an element from the list by using the iterator to its position. The pop_back() and pop_front()can also be used to quickly delete the first and last elements.
Example:
C++
#include <iostream>
#include<list>
using namespace std;
int main() {
list<int> l = {1, 3, 4, 2, 5};
// Deleting last element
l.pop_back();
// Deleting first element
l.pop_front();
// Deleting third element
auto it = l.begin();
advance(it, 2);
l.erase(it);
for (auto i : l)
cout << i << " ";
return 0;
}
Time Complexity
The below table lists the time complexity of the above operations on list:
Operation | Time Complexity |
---|
Insert at back | O(1) |
Insert at front | O(1) |
Remove from back | O(1) |
Remove from front | O(1) |
Access first element. | O(1) |
Access last element | O(1) |
Access element at any position | O(n) |
Find element by value | O(n) |
Traversing the list | O(n) |
Other Member Functions of List
Following is the list of all member functions of std::list class in C++:
Functions | Description |
---|
size() | Returns the number of elements in the list. |
---|
empty() | Checks if the list is empty. |
---|
rbegin() | Returns a reverse iterator pointing to the last element of the list. |
---|
rend() | Returns a reverse iterator pointing to the element before the first element. |
---|
clear() | Removes all elements from the list. |
---|
Explore
Introduction to C++
Basics
Core Concepts
C++ OOP
Standard Template Library(STL)
Practice C++
Top C++ DSA Related Problems