std::list in C++ s Primjerom

⚡ Pametni sažetak

std::list in C++ je spremnik sekvenci implementiran kao dvostruko povezana lista, koji omogućuje brzo umetanje i brisanje na bilo kojoj poziciji, a istovremeno pohranjuje elemente u nepovezanu memoriju i podržava dvosmjerni sekvencijalni pristup umjesto slučajnog pristupa.

  • 🔗 Dvostruko povezana lista: Svaki element zadržava veze na svoj prethodni i sljedeći čvor, tako da se podaci std::list nalaze u nepovezanoj memoriji.
  • Brzo umetanje i brisanje: Dodavanje ili uklanjanje elementa na poznatoj poziciji je konstantno vrijeme, za razliku od vektora koji pomiče elemente.
  • ???? Nema slučajnog pristupa: Do elemenata se dolazi sekvencijalnim obilaženjem s bilo kojeg kraja, tako da indeksiranje poput list[3] nije dostupno.
  • 🧩 Konstruktori: Konstruktori zadanih postavki, ispuna, raspona, kopiranja, premještanja i liste inicijalizatora grade std::list na različite načine.
  • 🛠️ Funkcije članova: push_front(), push_back(), insert(), erase(), size(), reverse() i merge() upravljaju sadržajem liste.
  • 🤖 AI pomoć: GitHub Copilot i slični asistenti scaffoldiraju std::list deklaracije, iteratore te umeću ili brišu logiku iz kratkog komentara.

std::list in C++

Što je std::list?

In C++, std::list se odnosi na spremnik za pohranu. std::list vam omogućuje umetanje i uklanjanje stavki s bilo kojeg mjesta. std::list je implementiran kao dvostruko povezana lista. To znači da se podacima liste može pristupiti dvosmjerno i sekvencijalno.

Popis standardne biblioteke predložaka ne podržava brzi nasumični pristup, ali podržava sekvencijalni pristup iz svih smjerova.

Elemente popisa možete rasporediti u različite dijelove memorije. Informacije potrebne za sekvencijalni pristup podacima pohranjuju se u spremnik. Std::list može se proširiti i smanjiti s oba kraja prema potrebi tijekom izvođenja. Interni alokator automatski ispunjava zahtjeve za pohranu.

Ove osobine postavljaju praktično pitanje: kada biste zapravo trebali posegnuti za popisom?

Zašto koristiti std::list?

Evo razloga za korištenje std::list:

  • std::list se bolje snalazi u usporedbi s drugim kontejnerima sekvenci poput niza i vektora.
  • Imaju bolje performanse u umetanju, premještanju i izvlačenjutracspajanje elemenata iz bilo kojeg položaja.
  • Std::list također radi bolje s algoritmima koji intenzivno izvode takve operacije.

S jasnim razlozima, sljedeći korak je sintaksa koja ga deklarira.

Sintaksa popisa

Da bismo definirali std::list, moramo uvesti datoteka zaglavlja. Ovo je sintaksa definicije std::list:

template < class Type, class Alloc =allocator<T> > class list;

Ovdje je opis gore navedenih parametara:

  • T – Definira tip sadržanog elementa. T možete zamijeniti bilo kojim tipom podataka, čak i korisnički definiranim tipovima.
  • Alloc – Definira tip objekta alokatora. Prema zadanim postavkama koristi predložak klase alokatora. Ovisi o vrijednosti i koristi jednostavan model alokacije memorije.

Primjer 1

#include <algorithm>
#include <iostream>
#include <list>
int main() {
	std::list<int> my_list = { 12, 5, 10, 9 };

	for (int x : my_list) {
		std::cout << x << '\n';
	}
}

Izlaz:

Izlaz primjera kreiranja i iteracije std::list

Evo snimke zaslona koda:

C++ kod koji kreira std::list i ispisuje je pomoću for petlje

Code Objašnjenje:

  1. Uključite datoteku zaglavlja algoritma da biste koristili njegove funkcije.
  2. Uključite datoteku zaglavlja iostream za korištenje njegovih funkcija.
  3. Uključite datoteku zaglavlja popisa da biste koristili njezine funkcije.
  4. Pozovite funkciju main(). Programsku logiku treba dodati unutar tijela ove funkcije.
  5. Napravite popis pod nazivom my_list sa skupom od 4 cijela broja.
  6. Koristiti za petlju za stvaranje varijable petlje x. Ova varijabla će se koristiti za iteraciju kroz elemente liste.
  7. Ispišite vrijednosti popisa na konzoli.
  8. Kraj tijela for petlje.
  9. Kraj tijela funkcije main().

C++ Popis funkcija

Ovo su uobičajene funkcije std::list:

funkcija Description
umetnuti() Ova funkcija umeće novu stavku prije pozicije na koju pokazuje iterator.
odgurnuti() Ova funkcija dodaje novu stavku na kraj popisa.
push_front() Dodaje novu stavku na početak popisa.
pop_front() Briše prvu stavku popisa.
veličina() Ova funkcija određuje broj elemenata popisa.
ispred() Za određivanje prvih stavki popisa.
leđa() Za određivanje zadnje stavke popisa.
obrnuti () Preokreće stavke popisa.
sjediniti() Spaja dvije sortirane liste.

Konstruktori

Evo popisa Funkcije koje pruža datoteka zaglavlja:

  • Zadani konstruktor std::list::list()- Stvara praznu listu, koja ima nula elemenata.
  • Konstruktor popune std::list::list()- Stvara popis s n elemenata i dodjeljuje vrijednost nula (0) svakom elementu.
  • Konstruktor raspona std::list::list() - stvara popis s mnogo elemenata u rasponu od prvog do zadnjeg.
  • Konstruktor kopiranja std::list::list()- Stvara popis s kopijom svakog elementa sadržanog u postojećem popisu.
  • Konstruktor pomicanja std::list::list()- stvara popis s elementima drugog popisa koristeći semantiku pomicanja.
  • Konstruktor popisa inicijalizatora std::list::list() - Stvara popis s elementima drugog popisa koristeći semantiku pomicanja.

Primjer 2

#include <iostream>
#include <list>
using namespace std;
int main(void) {
	list<int> l;
	list<int> l1 = { 10, 20, 30 };
	list<int> l2(l1.begin(), l1.end());
	list<int> l3(move(l1));  
	cout << "Size of list l: " << l.size() << endl;
	cout << "List l2 contents: " << endl;
	for (auto it = l2.begin(); it != l2.end(); ++it)
	      cout << *it << endl;
	cout << "List l3 contents: " << endl;
	for (auto it = l3.begin(); it != l3.end(); ++it)
		cout << *it << endl;
	return 0;
}

Izlaz:

Izlaz primjera konstruktora std::list

Evo snimke zaslona koda:

C++ kod koji demonstrira konstruktore std::list default, range i move

Code Objašnjenje:

  1. Uključite datoteku zaglavlja iostream za korištenje njegovih funkcija.
  2. Uključite datoteku zaglavlja popisa da biste koristili njezine funkcije.
  3. Uključite prostor imena std u kod da biste koristili njegove klase bez pozivanja.
  4. Pozovite funkciju main(). Programsku logiku treba dodati unutar tijela ove funkcije.
  5. Napravite praznu listu pod nazivom l.
  6. Napravite popis pod nazivom l1 sa skupom od 3 cijela broja.
  7. Napravite listu pod nazivom l2 sa svim elementima u listi pod nazivom l1, od početka do kraja.
  8. Napravite popis pod nazivom l3 koristeći semantiku premještanja. Lista l3 će imati isti sadržaj kao i lista l2.
  9. Ispišite veličinu popisa pod nazivom l na konzoli uz ostali tekst.
  10. Ispišite tekst na konzoli.
  11. Napravite iterator pod nazivom it i koristite ga za iteraciju preko elemenata popisa pod nazivom l2.
  12. Ispišite elemente liste s imenom l2 na konzoli.
  13. Ispišite tekst na konzoli.
  14. Napravite iterator pod nazivom it i koristite ga za iteraciju preko elemenata popisa pod nazivom l3.
  15. Ispišite elemente liste s imenom l3 na konzoli.
  16. Program mora vratiti vrijednost nakon uspješnog završetka.
  17. Kraj tijela funkcije main().

Svojstva kontejnera

Ovdje je popis svojstava spremnika:

Svojstvo Description
Slijed Spremnici niza poredaju svoje elemente u strogom linearnom nizu. Elementima se pristupa prema njihovom položaju u nizu.
Dvostruko povezana lista Svaki element ima informacije o tome kako locirati prethodni i sljedeći element. To omogućuje konstantno vrijeme za operacije umetanja i brisanja.
Svjestan alokatora Objekt alokatora koristi se za dinamičku izmjenu veličine pohrane.

Umetanje u popis

Postoje različite funkcije koje možemo koristiti za umetanje vrijednosti u popis. Demonstrirajmo to:

Primjer 3

#include <algorithm>
#include <iostream>
#include <list>
int main() {
	std::list<int> my_list = { 12, 5, 10, 9 };
	my_list.push_front(11);
	my_list.push_back(18);
	auto it = std::find(my_list.begin(), my_list.end(), 10);
	if (it != my_list.end()) {
		my_list.insert(it, 21);
	}
	for (int x : my_list) {
		std::cout << x << '\n';
	}
}

Izlaz:

Izlaz nakon umetanja elemenata u std::list

Evo snimke zaslona koda:

C++ kod koji koristi push_front, push_back i insert na std::list

Code Objašnjenje:

  1. Uključite datoteku zaglavlja algoritma da biste koristili njegove funkcije.
  2. Uključite datoteku zaglavlja iostream za korištenje njegovih funkcija.
  3. Uključite datoteku zaglavlja popisa da biste koristili njezine funkcije.
  4. Pozovite funkciju main(). Programsku logiku treba dodati unutar tijela ove funkcije.
  5. Napravite popis pod nazivom my_list sa skupom od 4 cijela broja.
  6. Umetnite element 11 na početak liste pod nazivom my_list.
  7. Umetnite element 18 na kraj liste pod nazivom my_list.
  8. Napravite iterator i pomoću njega pronađite element 10 s popisa my_list.
  9. Upotrijebite naredbu if da odredite je li gornji element pronađen ili ne.
  10. Umetnite element 21 prije gornjeg elementa ako je pronađen.
  11. Kraj tijela naredbe if.
  12. Koristite for petlju za stvaranje varijable petlje x. Ova će se varijabla koristiti za ponavljanje po elementima popisa.
  13. Ispišite vrijednosti popisa na konzoli.
  14. Kraj tijela for petlje.
  15. Kraj tijela funkcije main().

Elementi koji idu na popis mogu se jednako lako ukloniti.

Brisanje s popisa

Moguće je brisati stavke s popisa. Funkcija erase() omogućuje vam brisanje stavke ili niza stavki s popisa.

  • Da biste izbrisali jednu stavku, jednostavno proslijedite jedno mjesto cijelog broja. Stavka će biti izbrisana.
  • Za brisanje raspona, prosljeđujete početni i završni iterator. Demonstrirajmo to.

Primjer 4

#include <algorithm>
#include <iostream>
#include <list>
using namespace std;
int main() {
	std::list<int> my_list = { 12, 5, 10, 9 };
	cout << "List elements before deletion: ";
	for (int x : my_list) {
		std::cout << x << '\n';
	}
	list<int>::iterator i = my_list.begin();
	my_list.erase(i);
	cout << "\nList elements after deletion: ";
	for (int x : my_list) {
		std::cout << x << '\n';
	}
	return 0;
}

Izlaz:

Izlaz nakon brisanja elementa iz std::list

Evo snimke zaslona koda:

C++ kod koji koristi funkciju erase na std::list

Code Objašnjenje:

  1. Uključite datoteku zaglavlja algoritma da biste koristili njegove funkcije.
  2. Uključite datoteku zaglavlja iostream za korištenje njegovih funkcija.
  3. Uključite datoteku zaglavlja popisa da biste koristili njezine funkcije.
  4. Uključite prostor imena std u naš program kako biste koristili njegove klase bez pozivanja.
  5. Pozovite funkciju main(). Programsku logiku treba dodati unutar tijela ove funkcije.
  6. Napravite popis pod nazivom my_list sa skupom od 4 cijela broja.
  7. Ispišite tekst na konzoli.
  8. Koristite for petlju za stvaranje varijable petlje x. Ova će se varijabla koristiti za ponavljanje po elementima popisa.
  9. Ispišite vrijednosti popisa na konzoli.
  10. Kraj tijela for petlje.
  11. Napravite iterator i koji pokazuje na prvi element liste.
  12. Koristite funkciju erase() na koju ukazuje iterator i.
  13. Ispišite tekst na konzoli.
  14. Koristite for petlju za stvaranje varijable petlje x. Ova će se varijabla koristiti za ponavljanje po elementima popisa.
  15. Ispišite vrijednosti popisa na konzoli. Ovo dolazi nakon brisanja.
  16. Kraj tijela for petlje.
  17. Program mora vratiti vrijednost nakon uspješnog završetka.
  18. Kraj tijela funkcije main().

Pitanja i odgovori

std::vector pohranjuje elemente u susjednu memoriju s O(1) slučajnim pristupom, dok je std::list dvostruko povezana lista koja daje O(1) umetanja ili brisanja bilo gdje. Odaberite vector za indeksiranje, a list za česta umetanja u sredinu.

Ne. std::list nema operator slučajnog pristupa, pa se list[2] ne kompajlira. Do elementa dolazite iteracijom od begin() ili end() čvor po čvor, što za duboku poziciju košta linearno O(n) vremena.

std::list je dvostruko povezana lista koja se kreće u oba smjera i podržava push_back. std::forward_list je jednostruko povezana lista koja se kreće samo naprijed, koristi manje memorije po čvoru i ne nudi size() ili reverse iteratore.

Pozovite funkciju članicu my_list.sort(), koja se izvršava za otprilike N log N i održava jednake elemente stabilnima. Algoritam std::sort neće raditi jer treba iteratore s nasumičnim pristupom. Za silazni redoslijed proslijedite std::greater funkciji sort().

Umetanje ili brisanje čvora traje konstantno O(1) vrijeme nakon što iterator zadržite na poziciji, jer se mijenjaju samo susjedni pokazivači. Pronalaženje te pozicije prvim obilaženjem i dalje košta O(n) vremena.

Da. std::list nije skup, pa slobodno pohranjuje ponovljene vrijednosti. Svaki push_back, push_front ili insert dodaje novi čvor bez obzira na postojeći sadržaj. Koristite std::set kada trebate odbaciti duplicirane elemente.

Da. GitHub kopilot piše deklaracije std::list, petlje iteratora te umeće ili briše pozive iz kratkog komentara ili naziva funkcije. Često predlaže std::vector kada kontinuirana pohrana bolje odgovara zadatku.

AI asistenti za kodiranje automatski dovršavaju STL kod kontejnera, označavaju pogrešnu upotrebu iteratora, pretvaraju std::list u std::vector i objašnjavaju kompromise u složenosti. Ubrzavaju učenje STL-a, iako svaki prijedlog i dalje treba pregledati.

Sažmite ovu objavu uz: