std::lijst in C++ met Voorbeeld

⚡ Slimme samenvatting

std::lijst in C++ is een sequentiecontainer die is geïmplementeerd als een dubbelgelinkte lijst, waardoor snelle invoeging en verwijdering op elke positie mogelijk is, terwijl elementen in niet-aaneengesloten geheugen worden opgeslagen en bidirectionele sequentiële toegang in plaats van willekeurige toegang wordt ondersteund.

  • 🔗 Dubbel gekoppelde lijst: Elk element behoudt links naar het vorige en volgende knooppunt, waardoor de gegevens van std::list in niet-aaneengesloten geheugen worden opgeslagen.
  • Snel invoegen en verwijderen: Het toevoegen of verwijderen van een element op een bekende positie kost constante tijd, in tegenstelling tot een vector die elementen verschuift.
  • ???? Geen willekeurige toegang: Elementen worden bereikt door sequentiële traversering vanaf beide uiteinden, dus indexering zoals list[3] is niet beschikbaar.
  • 🧩 Constructeurs: De constructors Default, fill, range, copy, move en initializer-list bouwen een std::list op verschillende manieren.
  • Lidfuncties: push_front(), push_back(), insert(), erase(), size(), reverse() en merge() beheren de inhoud van de lijst.
  • 🤖 AI-assistentie: GitHub Copilot en vergelijkbare hulpmiddelen genereren std::list-declaraties, iterators en invoeg- of verwijderlogica op basis van een korte opmerking.

std::lijst in C++

Wat is een std::lijst?

In C++De std::list verwijst naar een opslagcontainer. Met de std::list kun je overal items invoegen en verwijderen. De std::list is geïmplementeerd als een dubbelgelinkte lijst. Dit betekent dat lijstgegevens bidirectioneel en sequentieel toegankelijk zijn.

De standaard sjabloonbibliotheek ondersteunt geen snelle willekeurige toegang, maar wel sequentiële toegang vanuit alle richtingen.

U kunt lijstelementen in verschillende geheugenblokken verspreiden. De informatie die nodig is voor sequentiële toegang tot gegevens wordt opgeslagen in een container. De std::list kan tijdens runtime aan beide kanten worden uitgebreid en verkleind. Een interne allocator voldoet automatisch aan de opslagvereisten.

Deze eigenschappen roepen een praktische vraag op: wanneer moet je nu eigenlijk een lijst erbij pakken?

Waarom std::list gebruiken?

Hieronder volgen de redenen om std::list te gebruiken:

  • De std::list presteert beter in vergelijking met andere sequentiecontainers zoals array en vector.
  • Ze presteren beter bij het invoegen, verplaatsen en verwijderen.tracelementen vanuit elke positie.
  • De std::list werkt ook beter met algoritmen die dergelijke bewerkingen intensief uitvoeren.

Nu de redenen duidelijk zijn, is de volgende stap de syntaxis die er een declareert.

Syntaxis van lijst

Om de std::list te definiëren, moeten we de header-bestand. Hier is de syntaxis van de std::list-definitie:

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

Hier volgt een beschrijving van de bovenstaande parameters:

  • T – Definieert het type element dat erin is opgenomen. U kunt T vervangen door elk gegevenstype, zelfs door door de gebruiker gedefinieerde typen.
  • Alloc – Definieert het type van het allocator-object. Standaard wordt de allocator-klassetemplate gebruikt. Het is waardeafhankelijk en maakt gebruik van een eenvoudig geheugenallocatiemodel.

Voorbeeld 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';
	}
}

Output:

Uitvoer van het voorbeeld voor het aanmaken en doorlopen van een std::list

Hier is een screenshot van de code:

C++ Code die een `std::list` aanmaakt en deze afdrukt met een `for`-lus.

Code Uitleg:

  1. Voeg het headerbestand van het algoritme toe om de functies ervan te gebruiken.
  2. Voeg het iostream-headerbestand toe om de functies ervan te gebruiken.
  3. Voeg het lijstkopbestand toe om de functies ervan te gebruiken.
  4. Roep de functie main() aan. De programmalogica moet worden toegevoegd aan de hoofdtekst van deze functie.
  5. Maak een lijst met de naam my_list met een set van 4 gehele getallen.
  6. Gebruik een for loop Om een ​​lusvariabele x aan te maken. Deze variabele wordt gebruikt om door de elementen van de lijst te itereren.
  7. Druk de waarden van de lijst op de console af.
  8. Einde van de hoofdtekst van de for-lus.
  9. Einde van de hoofdtekst van de functie main().

C++ Lijst Functies

Hier zijn de algemene std::list-functies:

Functie Beschrijving
invoegen () Deze functie voegt een nieuw item in vóór de positie waar de iterator naar wijst.
terugduwen() Deze functie voegt een nieuw item toe aan het einde van de lijst.
push_front() Er wordt een nieuw item toegevoegd aan de voorkant van de lijst.
pop_front() Het verwijdert het eerste item van de lijst.
grootte() Deze functie bepaalt het aantal lijstelementen.
voorkant() Om de eerste items van de lijst te bepalen.
rug() Om het laatste item van de lijst te bepalen.
omgekeerde() Het draait de lijstitems om.
samenvoegen() Het voegt twee gesorteerde lijsten samen.

Constructeurs

Hier is de lijst van functies verstrekt door de headerbestand:

  • Standaardconstructor std::list::list()- Het creëert een lege lijst met nul elementen.
  • Fill constructor std::list::list()- Het creëert een lijst met n elementen en kent een waarde van nul (0) toe aan elk element.
  • Bereikconstructor std::list::list()- creëert een lijst met veel elementen in het bereik van eerste tot laatste.
  • Kopieer constructor std::list::list()- Het creëert een lijst met een kopie van elk element in de bestaande lijst.
  • Move constructor std::list::list()- creëert een lijst met de elementen van een andere lijst met behulp van move-semantiek.
  • Initializer list constructor std::list::list() -Het creëert een lijst met de elementen van een andere lijst met behulp van verplaatsingssemantiek.

Voorbeeld 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;
}

Output:

Uitvoer van het std::list-constructorvoorbeeld

Hier is een screenshot van de code:

C++ Code die de standaard-, bereik- en verplaatsingsconstructors van std::list demonstreert.

Code Uitleg:

  1. Voeg het iostream-headerbestand toe om de functies ervan te gebruiken.
  2. Voeg het lijstkopbestand toe om de functies ervan te gebruiken.
  3. Neem de std-naamruimte op in de code om de klassen ervan te gebruiken zonder deze aan te roepen.
  4. Roep de functie main() aan. De programmalogica moet worden toegevoegd aan de hoofdtekst van deze functie.
  5. Maak een lege lijst met de naam l.
  6. Maak een lijst met de naam l1 met een set van 3 gehele getallen.
  7. Maak een lijst met de naam l2 met alle elementen in de lijst met de naam l1, van het begin tot het einde.
  8. Maak een lijst met de naam l3 met behulp van verplaatsingssemantiek. De lijst l3 zal dezelfde inhoud hebben als de lijst l2.
  9. Druk de grootte van de lijst met de naam l af op de console, samen met andere tekst.
  10. Druk wat tekst af op de console.
  11. Maak een iterator met de naam en gebruik deze om de elementen van de lijst met de naam l2 te herhalen.
  12. Druk de elementen van de lijst met de naam l2 af op de console.
  13. Druk wat tekst af op de console.
  14. Maak een iterator met de naam en gebruik deze om de elementen van de lijst met de naam l3 te herhalen.
  15. Druk de elementen van de lijst met de naam l3 af op de console.
  16. Het programma moet waarde retourneren na succesvolle voltooiing.
  17. Einde van de hoofdtekst van de functie main().

Container eigenschappen

Hier is de lijst met containereigenschappen:

Eigendom Beschrijving
Volgorde Sequentiecontainers rangschikken hun elementen in een strikte lineaire volgorde. Elementen zijn toegankelijk via hun positie in de reeks.
Dubbel gelinkte lijst Elk element heeft informatie over hoe vorige en volgende elementen te vinden zijn. Dit zorgt voor constante tijd voor invoeg- en verwijderbewerkingen.
Allocator-bewust Een allocatorobject wordt gebruikt om de opslaggrootte dynamisch te wijzigen.

Invoegen in een lijst

Er zijn verschillende functies die we kunnen gebruiken om waarden in een lijst in te voegen. Laten we dit demonstreren:

Voorbeeld 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';
	}
}

Output:

Uitvoer na het invoegen van elementen in een std::list

Hier is een screenshot van de code:

C++ Code die gebruikmaakt van `push_front`, `push_back` en `insert` op een `std::list`.

Code Uitleg:

  1. Voeg het headerbestand van het algoritme toe om de functies ervan te gebruiken.
  2. Voeg het iostream-headerbestand toe om de functies ervan te gebruiken.
  3. Voeg het lijstkopbestand toe om de functies ervan te gebruiken.
  4. Roep de functie main() aan. De programmalogica moet worden toegevoegd aan de hoofdtekst van deze functie.
  5. Maak een lijst met de naam my_list met een set van 4 gehele getallen.
  6. Voeg element 11 in aan de voorkant van de lijst met de naam my_list.
  7. Voeg element 18 in aan het einde van de lijst met de naam my_list.
  8. Maak er een iterator van en gebruik deze om element 10 uit de lijst my_list te vinden.
  9. Gebruik een if-instructie om te bepalen of het bovenstaande element is gevonden of niet.
  10. Voeg element 21 in vóór het bovenstaande element als het is gevonden.
  11. Einde van de hoofdtekst van de if-instructie.
  12. Gebruik een for-lus om een ​​lusvariabele x te maken. Deze variabele wordt gebruikt om de lijstelementen te herhalen.
  13. Druk de waarden van de lijst op de console af.
  14. Einde van het lichaam van de lus.
  15. Einde van de hoofdtekst van de functie main().

Elementen die in een lijst worden opgenomen, kunnen er net zo makkelijk weer uit worden verwijderd.

Verwijderen uit een lijst

Het is mogelijk om items uit een lijst te verwijderen. Met de functie erase() kun je een item of een reeks items uit een lijst verwijderen.

  • Om een ​​enkel item te verwijderen, geeft u eenvoudigweg één gehele positie door. Het item wordt verwijderd.
  • Om een ​​bereik te verwijderen, geef je de begin- en einditerator door. Laten we dit demonstreren.

Voorbeeld 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;
}

Output:

Uitvoer na het verwijderen van een element uit een std::list

Hier is een screenshot van de code:

C++ Code die de erase-functie gebruikt op een std::list.

Code Uitleg:

  1. Voeg het headerbestand van het algoritme toe om de functies ervan te gebruiken.
  2. Voeg het iostream-headerbestand toe om de functies ervan te gebruiken.
  3. Voeg het lijstkopbestand toe om de functies ervan te gebruiken.
  4. Neem de std-naamruimte op in ons programma om de klassen ervan te gebruiken zonder deze aan te roepen.
  5. Roep de functie main() aan. De programmalogica moet worden toegevoegd aan de hoofdtekst van deze functie.
  6. Maak een lijst met de naam my_list met een set van 4 gehele getallen.
  7. Druk wat tekst af op de console.
  8. Gebruik een for-lus om een ​​lusvariabele x te maken. Deze variabele wordt gebruikt om de lijstelementen te herhalen.
  9. Druk de waarden van de lijst op de console af.
  10. Einde van de hoofdtekst van de for-lus.
  11. Maak een iterator i die naar het eerste element van de lijst verwijst.
  12. Gebruik de functie erase() waar de iterator i naar wijst.
  13. Druk wat tekst af op de console.
  14. Gebruik een for-lus om een ​​lusvariabele x te maken. Deze variabele wordt gebruikt om de lijstelementen te herhalen.
  15. Druk de waarden van de lijst op de console af. Dit komt na verwijdering.
  16. Einde van de hoofdtekst van de for-lus.
  17. Het programma moet bij succesvolle voltooiing een waarde retourneren.
  18. Einde van de hoofdtekst van de functie main().

Veelgestelde vragen

`std::vector` slaat elementen op in aaneengesloten geheugen met O(1) willekeurige toegang, terwijl `std::list` een dubbelgelinkte lijst is die O(1) invoeging of verwijdering op elke willekeurige plek mogelijk maakt. Kies `vector` voor indexering en `list` voor frequente invoegingen in het midden.

Nee. std::list heeft geen operator voor willekeurige toegang, dus list[2] compileert niet. Je bereikt een element door te itereren vanaf begin() of end() één knooppunt per keer, wat lineaire O(n) tijd kost voor een diepe positie.

std::list is een dubbelgelinkte lijst die in beide richtingen kan worden doorlopen en push_back ondersteunt. std::forward_list is een enkelgelinkte lijst die alleen vooruit beweegt, minder geheugen per knooppunt gebruikt en geen size()- of reverse-iterators biedt.

Roep de lidfunctie my_list.sort() aan, die ongeveer N log N rekentijd nodig heeft en gelijke elementen stabiel houdt. Het std::sort-algoritme werkt niet omdat het iterators met willekeurige toegang vereist. Geef std::greater door aan sort() voor aflopende sortering.

Het invoegen of verwijderen van een knooppunt kost constant O(1) tijd zodra je een iterator naar de positie hebt, omdat alleen de aangrenzende pointers veranderen. Het vinden van die positie door middel van traversering kost nog steeds O(n) tijd.

Ja. Een `std::list` is geen set, dus het slaat herhaalde waarden zonder problemen op. Elke `push_back`, `push_front` of `insert` voegt een nieuw knooppunt toe, ongeacht de bestaande inhoud. Gebruik `std::set` wanneer je dubbele elementen wilt afwijzen.

Ja. GitHub-copiloot Het schrijft std::list-declaraties, iteratorlussen en invoeg- of verwijderingsaanroepen vanuit een korte opmerking of functienaam. Het suggereert vaak std::vector wanneer aaneengesloten opslag beter geschikt is voor de taak.

AI-codeerassistenten vullen STL-containercode automatisch aan, signaleren onjuist gebruik van iterators, converteren een std::list naar een std::vector en leggen afwegingen in complexiteit uit. Ze versnellen het leren van de STL, hoewel elke suggestie nog steeds moet worden beoordeeld.

Vat dit bericht samen met: