MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

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}