Contents
List
A list is also a sequential container similar to a vector but allows for insertions and deletions in a more efficient manner. It does this because the internal structure is not a contiguous sequence of memory but built using nodes. STL uses a double linked list as the implementation.File: list1.cpp
// C++ program to demonstrate the use of list containers #include <iostream> #include <list> using namespace std; int main() { // defining list list<int> list1 ; for( int i1=1 ; i1<=5 ; i1++ ) { list1.push_back( i1 ) ; } list1.push_front( 6 ) ; list1.insert( list1.begin() , 14 ) ; list<int>::iterator it = list1.begin() ; advance(it, 2) ; list1.insert( it , 15 ) ; for (it = list1.begin() ; it != list1.end() ; it++ ) { cout << *it << ' '; } cout << endl ; return 0; } $ g++ list1.cpp ; ./a.exe 14 6 15 1 2 3 4 5 Some of the methods for a list class are: push_back push_front insert front() returns an element at the front back() returns an element at the back clear() removes all the elements empty() checks if the list is empty resize() changes the size reverse() reverse the list
File: list2.cpp
// C++ program to demonstrate the use of list containers #include <iostream> #include <list> #include <vector> #include <chrono> #include <thread> using namespace std; class Timer { public: chrono::steady_clock::time_point start_time ; chrono::steady_clock::time_point end_time ; void startTime() { start_time = chrono::steady_clock::now() ; } void endTime() { end_time = chrono::steady_clock::now() ; } void printTime() { chrono::milliseconds elapsed_ms = chrono::duration_cast<chrono::milliseconds>(end_time - start_time); cout << "Execution time: " << elapsed_ms.count() << " milliseconds" << endl; } }; //-------------------------------------------------------- int main() { // defining list Timer timerObject ; list<int> list1 ; vector<int> vec1 ; int noElements = 1000000 ; timerObject.startTime() ; for( int i1=1 ; i1 <= noElements ; i1++ ) { vec1.push_back( i1 ) ; } timerObject.endTime() ; cout << "Vector add elements to end: " << endl; timerObject.printTime() ; timerObject.startTime() ; for( int i1=1 ; i1 <= noElements ; i1++ ) { list1.push_back( i1 ) ; } timerObject.endTime() ; cout << "List add elements to end: " << endl; timerObject.printTime() ; //---------------------------------------------- int noElementsToDelete = 1000 ; timerObject.startTime() ; for( int i1=2 ; i1 <= noElementsToDelete ; i1++ ) { vec1.erase(vec1.begin() + 2) ; } timerObject.endTime() ; cout << "Vector delete elements: " << endl; timerObject.printTime() ; timerObject.startTime() ; list<int>::iterator it = list1.begin(); for( int i1=2 ; i1 <= noElementsToDelete ; i1++ ) { advance(it, 1); list1.erase(it) ; } timerObject.endTime() ; cout << "List delete elements time: " << endl; timerObject.printTime() ; //---------------------------------------------- //Insert elements in the middle noElements = 1000 ; timerObject.startTime() ; for( int i1=1 ; i1 <= noElements ; i1++ ) { vec1.insert(vec1.begin() + 2, i1 ); ; } timerObject.endTime() ; cout << "Vector insert elements in middle: " << endl; timerObject.printTime() ; timerObject.startTime() ; list1.clear() ; list1.push_back( 1 ) ;list1.push_back( 2 ) ; it = list1.begin() ; advance(it, 2) ; for( int i1=1 ; i1 <= noElements ; i1++ ) { list1.insert( it , i1 ) ; } timerObject.endTime() ; cout << "List insert elements in middle: " << endl; timerObject.printTime() ; return 0; } $ ./a.exe Vector add elements to end: Execution time: 17 milliseconds List add elements to end: Execution time: 128 milliseconds Vector delete elements: Execution time: 298 milliseconds List delete elements time: Execution time: 76 milliseconds Vector insert elements in middle: Execution time: 368 milliseconds List insert elements in middle: Execution time: 89 milliseconds To add elements at the end of the container the vector is more efficient because it adds one element after another. The list has to create a node and add that node to the list. Deletion and insertion of elements is more efficiently done by the list than the vecotr.
Exercise
File: list_ex1.cpp
// C++ program to demonstrate the use of list containers #include <iostream> #include <list> #include <vector> #include <chrono> #include <thread> using namespace std; int main() { list<int> list1 = { 1 , 2, 3, 4 , 5 } ; //reverse the list //use the reverse function //Declare an iterator to the list list<int>::iterator it = list1.begin(); //Advance the iterator by 2 //erase the element pointed to by it // element is 3. Use the erase function //print the first and last elements using the //function front and back //print the size of the list // use the size function //iterate the list incrementing each element for( it = list1.begin() ; it != list1.end() ; it++ ) { } //print the list using for range loop for( int x1 : list1 ) cout << x1 << " " ; cout << endl ; return 0; }
File: list_ex2.cpp
// C++ program to demonstrate the use of list containers #include <iostream> #include <list> using namespace std; int main() { // We have a list 1 containing 6 elements //Take the elements out of list 1 and insert them into list 2 //so that the elements in list 2 are sorted. //Do not use a library STL sort function. //Iterate throught the list1 elements and insert into //list2 one element at a time by finding the correct //position for it. //4 2 3 5 1 16 //Take 4 out and put it in list2 // Take 2 out and place it before 4 in list2 list<int> list1 ; list<int> list2 ; list1.push_back( 4 ) ;list1.push_back( 2 ) ; list1.push_back( 3 ) ;list1.push_back( 5 ) ; list1.push_back( 1 ) ; list1.push_back( 16 ) ; list<int>::iterator it = list1.begin() ; list<int>::iterator it2 = list2.begin() ; for( int a1 : list1 ) { cout << a1 << " " ; } cout << endl ; return 0; }
Solutions
File: list_ex1_s.cpp
File: list_ex2_s.cpp