List
Containerul list reprezintă o listă dublu înlănțuită, adică o listă în care fiecare element are referințe către elementul precedent și către cel următor. Datorită acestui lucru, ne putem deplasa prin listă atât înainte, cât și înapoi. Pentru a utiliza lista, este necesar să includem fișierul antet list.
Crearea unei liste:
#include <list>
int main()
{
std::list<int> list1; // listă goală
std::list<int> list2(5); // lista list2 conține 5 numere, fiecare element are valoarea implicită
std::list<int> list3(5, 2); // lista list3 conține 5 numere, fiecare număr este egal cu 2
std::list<int> list4{ 1, 2, 4, 5 }; // lista list4 conține numerele 1, 2, 4, 5
std::list<int> list5 = { 1, 2, 3, 5 }; // lista list5 conține numerele 1, 2, 3, 5
std::list<int> list6(list4); // lista list6 este o copie a listei list4
std::list<int> list7 = list4; // lista list7 este o copie a listei list4
}
Obținerea elementelor
Spre deosebire de alte containere, pentru tipul list nu este definită operația de accesare prin index sau funcția at(), care realizează o sarcină similară.
Totuși, pentru containerul list pot fi folosite funcțiile front() și back(), care returnează respectiv primul și ultimul element.
Pentru a accesa elementele care se află în mijloc (după primul și până la ultimul element), trebuie să parcurgem elementele folosind bucle sau iteratori:
#include <iostream>
#include <list>
int main()
{
std::list<int> numbers{ 1, 2, 3, 4, 5 };
int first {numbers.front() }; // 1
int last { numbers.back() }; // 5
std::cout << "First: " << first << std::endl;
std::cout << "Last: " << last << std::endl;
// parcurgere cu buclă
for (int n : numbers)
std::cout << n << "\t";
std::cout << std::endl;
// parcurgere cu iteratori
for (auto iter = numbers.begin(); iter != numbers.end(); iter++)
{
std::cout << *iter << "\t";
}
std::cout << std::endl;
}
Dimensiunea listei
Pentru a obține dimensiunea listei se poate folosi funcția size():
std::list<int> numbers{ 1, 2, 3, 4, 5 };
int size = numbers.size(); // 5
Funcția empty() permite verificarea dacă lista este goală. Dacă este goală, funcția returnează valoarea true, altfel returnează false:
std::list<int> numbers{ 1, 2, 3, 4, 5 };
if (numbers.empty())
std::cout << "The list is empty" << std::endl;
else
std::cout << "The list is not empty" << std::endl;
Cu ajutorul funcției resize() se poate modifica dimensiunea listei. Această funcție are două forme:
- resize(n): păstrează primele n elemente din listă. Dacă lista are mai multe elemente, acestea sunt tăiate. Dacă lista are mai puține elemente, se adaugă elemente suplimentare cu valoarea implicită
- resize(n, value): păstrează de asemenea primele n elemente. Dacă lista are mai puține elemente, se adaugă elemente suplimentare cu valoarea value
Utilizarea funcției:
std::list<int> numbers{ 1, 2, 3, 4, 5, 6 };
numbers.resize(4); // păstrăm primele patru elemente - numbers = {1, 2, 3, 4}
numbers.resize(6, 8); // numbers = {1, 2, 3, 4, 8, 8}
Modificarea elementelor listei
Funcția assign() permite înlocuirea tuturor elementelor din listă cu un set specificat. Are următoarele forme:
- assign(il): înlocuiește conținutul containerului cu elementele din lista de inițializare il
- assign(n, value): înlocuiește conținutul containerului cu n elemente, fiecare având valoarea value
- assign(begin, end): înlocuiește conținutul containerului cu elementele din intervalul indicat de iteratorii begin și end
Utilizarea funcției:
std::list<int> numbers { 1, 2, 3, 4, 5 };
numbers.assign({ 21, 22, 23, 24, 25 }); // numbers = { 21, 22, 23, 24, 25 }
numbers.assign(4, 3); // numbers = {3, 3, 3, 3}
std::list<int> values { 6, 7, 8, 9, 10, 11 };
auto start = ++values.begin(); // iteratorul indică al doilea element din values
auto end = values.end();
numbers.assign(start, end); // numbers = { 7, 8, 9, 10, 11 }
Funcția swap() schimbă valorile între două liste:
std::list<int> list1{ 1, 2, 3, 4, 5 };
std::list<int> list2{ 6, 7, 8, 9};
list1.swap(list2);
// list1 = { 6, 7, 8, 9};
// list2 = { 1, 2, 3, 4, 5 };
Adăugarea elementelor
Pentru adăugarea de elemente în containerul list se folosesc următoarele funcții:
- push_back(val): adaugă valoarea val la sfârșitul listei
- push_front(val): adaugă valoarea val la începutul listei
- emplace_back(val): adaugă valoarea val la sfârșitul listei
- emplace_front(val): adaugă valoarea val la începutul listei
- emplace(pos, val): inserează elementul val în poziția indicată de iteratorul pos. Returnează un iterator către elementul adăugat
- insert(pos, val): inserează elementul val în poziția indicată de iteratorul pos, similar cu emplace
- insert(pos, n, val): inserează n elemente val începând din poziția pos
- insert(pos, begin, end): inserează începând din poziția pos elementele din alt container aflate între iteratorii begin și end
- insert(pos, values): inserează lista de valori values începând din poziția pos
Funcțiile push_back(), push_front(), emplace_back() și emplace_front():
std::list<int> numbers{ 1, 2, 3, 4, 5 };
numbers.push_back(23); // { 1, 2, 3, 4, 5, 23 }
numbers.push_front(15); // { 15, 1, 2, 3, 4, 5, 23 }
numbers.emplace_back(24); // { 15, 1, 2, 3, 4, 5, 23, 24 }
numbers.emplace_front(14); // { 14, 15, 1, 2, 3, 4, 5, 23, 24 }
Adăugarea în mijlocul listei cu emplace():
std::list<int> numbers{ 1, 2, 3, 4, 5 };
auto iter = ++numbers.cbegin(); // iteratorul indică al doilea element
numbers.emplace(iter, 8); // adăugăm după primul element numbers = { 1, 8, 2, 3, 4, 5};
Adăugarea în mijlocul listei cu insert():
std::list<int> numbers1{ 1, 2, 3, 4, 5 };
auto iter1 = numbers1.cbegin(); // iteratorul indică primul element
numbers1.insert(iter1, 0); // adăugăm la începutul listei
//numbers1 = { 0, 1, 2, 3, 4, 5};
std::list<int> numbers2{ 1, 2, 3, 4, 5 };
auto iter2 = numbers2.cbegin(); // iteratorul indică primul element
numbers2.insert(++iter2, 3, 4); // adăugăm după primul element trei valori de 4
//numbers2 = { 1, 4, 4, 4, 2, 3, 4, 5};
std::list<int> values { 10, 20, 30, 40, 50 };
std::list<int> numbers3{ 1, 2, 3, 4, 5 };
auto iter3 = numbers3.cbegin(); // iteratorul indică primul element
// adăugăm la început toate elementele din values
numbers3.insert(iter3, values.begin(), values.end());
//numbers3 = { 10, 20, 30, 40, 50, 1, 2, 3, 4, 5};
std::list<int> numbers4{ 1, 2, 3, 4, 5 };
auto iter4 = numbers4.cend(); // iteratorul indică poziția după ultimul element
// adăugăm la sfârșit lista de trei elemente
numbers4.insert(iter4, { 21, 22, 23 });
//numbers4 = { 1, 2, 3, 4, 5, 21, 22, 23};
Ștergerea elementelor
Pentru ștergerea elementelor din containerul list pot fi folosite următoarele funcții:
- clear(): șterge toate elementele
- pop_back(): șterge ultimul element
- pop_front(): șterge primul element
- erase(p): șterge elementul indicat de iteratorul p
- erase(begin, end): șterge elementele din intervalul definit de iteratorii begin și end
Utilizarea funcțiilor:
std::list<int> numbers { 1, 2, 3, 4, 5 };
numbers.pop_front(); // numbers = { 2, 3, 4, 5 }
numbers.pop_back(); // numbers = { 2, 3, 4 }
numbers.clear(); // numbers ={}
numbers = { 1, 2, 3, 4, 5 };
auto iter = numbers.cbegin(); // iterator la primul element
numbers.erase(iter); // ștergem primul element
// numbers = { 2, 3, 4, 5 }
numbers = { 1, 2, 3, 4, 5 };
auto begin = numbers.begin(); // iterator la primul element
auto end = numbers.end(); // iterator la ultimul element
numbers.erase(++begin, --end); // ștergem de la al doilea până la penultimul
//numbers = {1, 5}