Freunde und Jungs, wir sehen uns wieder. In dieser Ausgabe erkläre ich euch die Verwendung von Listen. Wenn es euch nach der Lektüre inspiriert, hinterlasst doch bitte einen Kommentar. Ich wünsche euch, dass all eure Wünsche in Erfüllung gehen!
Spalte C-Sprache:C-Sprache: Vom Anfänger zum Meister
Datenstrukturspalte:Datenstruktur
Personenhauptnummer:stackY,
C + + Version:C++
Linux-Version:Linux
Inhaltsverzeichnis
3. Der Iterator der Liste ist ungültig
1. Einführung in die Liste
Liste der offiziellen Dokumentreferenzen
Ähnlich, die in der Datenstruktur erwähnt wirdZirkuläre verknüpfte Liste mit bidirektionalem Kopf
- 1. Liste ist ein sequentieller Container, der an jeder Position innerhalb des konstanten Bereichs eingefügt und gelöscht werden kann, und der Container kann in beide Richtungen vorwärts und rückwärts iteriert werden.
- 2. Die unterste Ebene der Liste ist eine doppelt verknüpfte Listenstruktur. Jedes Element in der doppelt verknüpften Liste wird in einem unabhängigen Element gespeichert Knoten, die nicht miteinander in Beziehung stehen. Der Knoten zeigt über Zeiger auf sein vorheriges und nächstes Element.
- 3. List ist Forward_list sehr ähnlich: Der Hauptunterschied besteht darin, dass forward_list eine einfach verknüpfte Liste ist, nur vorwärts iterieren kann und Es wurde einfacher und effizienter gemacht.
- 4. Im Vergleich zu anderen sequentiellen Containern (Array, Vektor, Deque) ist list beim Einfügen und Entfernen von Elementen an jeder Position normalerweise besser.
- 5. Im Vergleich zu anderen sequentiellen Containern besteht der größte Fehler von list und forward_list darin, dass sie keinen wahlfreien Zugriff an irgendeinem Ort unterstützen, Beispiel: Um auf das 6. Element der Liste zuzugreifen, müssen Sie von einer bekannten Position (z. B. Kopf oder Ende) zu dieser Position iterieren. Das Iterieren an dieser Position erfordert einen linearen Zeitaufwand; die Liste benötigt außerdem etwas zusätzlichen Speicherplatz, um jeweils etwas zu speichern Element. Mit Knoten verknüpfte Informationen (dies kann ein wichtiger Faktor für große Listen sein, in denen kleinere Elemente gespeichert sind).
2. Verwendung der Liste
Liste muss beim Lernen gelernt werdenDokumente anzeigen:Offizielle Dokumentreferenz auflisten< a i=4>, Liste ist in der Praxis sehr wichtig. In der Praxis müssen wir nur mit gängigen Schnittstellen vertraut sein. Im Folgenden werden die Schnittstellen aufgeführt, auf die wir uns konzentrieren müssen.
2.1 Definition der Liste
Konstruktor ((Konstruktor)) | Schnittstellenbeschreibung |
Liste (size_type n, const value_type& val = value_type()) | Die erstellte Liste enthält n Elemente mit dem Wert val |
Liste() | Erstellen Sie eine leere Liste |
Liste (const list& x) | Konstruktor kopieren |
Liste (InputIterator zuerst, InputIterator zuletzt) | Erstellen Sie eine Liste mit Elementen im Bereich [erster, letzter] |
Bevor Sie die Liste verwenden, müssen Sie die der Liste entsprechende Header-Datei einbinden:#include <list>
void list_test1() { //空构造 list<int> lt1; //n个val list<string> lt2(10, "0x0"); //迭代器区间 vector<int> v = { 0,1,2,3,4,5,6,7,8,9 }; list<int> lt3(v.begin() + 2, v.end()); //拷贝构造 list<string> lt4(lt2); }
2.2 Iterator
Funktionsdeklaration | Schnittstellenbeschreibung |
Anfang + Ende |
Gibt einen Iterator zum ersten Element + einen Iterator zur nächsten Position des letzten Elements zurück |
rbegin + rend |
Gibt den Reverse_iterator des ersten Elements zurück, das die Endposition ist, und gibt die nächste Position des letzten Elements zurück Reverse_iterator, das ist die Anfangsposition |
void list_test2() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); //正向迭代器 list<int>::iterator it = lt.begin(); //auto it = lt.begin(); while (it != lt.end()) { cout << *it << " "; it++; } cout << endl; //反向迭代器 list<int>::reverse_iterator rit = lt.rbegin(); //auto rit = lt.rbegin(); while (rit != lt.rend()) { cout << *rit << " "; rit++; } cout << endl; //范围for for (auto e : lt) { cout << e << " "; } cout << endl; }
2.3 Raumwachstum
Funktionsdeklaration | Schnittstellenbeschreibung |
leer | Überprüfen Sie, ob die Liste leer ist. Geben Sie „true“ zurück, wenn sie leer ist, andernfalls geben Sie „false“ zurück |
Größe | Gibt die Anzahl der gültigen Knoten in der Liste zurück |
void list_test3() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); cout << lt.empty() << endl; size_t sz = lt.size(); cout << sz << endl; }
2.4 Zugang
Funktionsdeklaration | Schnittstellenbeschreibung |
Vorderseite | Gibt einen Verweis auf den Wert im ersten Knoten der Liste zurück |
zurück | Gibt einen Verweis auf den Wert im letzten Knoten der Liste zurück |
void list_test4() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); cout << lt.front() << endl; cout << lt.back() << endl; }
2.5 Änderung
Funktionsdeklaration | Schnittstellenbeschreibung |
push_front | Fügen Sie vor dem ersten Element der Liste ein Element mit dem Wert val ein |
pop_front | Löschen Sie das erste Element in der Liste |
push_back | Fügen Sie am Ende der Liste ein Element mit dem Wert val ein |
Pop zurück | Löschen Sie das letzte Element in der Liste |
einfügen | Fügen Sie ein Element mit dem Wert val an der Listenposition ein |
löschen | Löschen Sie das Element an der Listenposition |
tauschen | Tauschen Sie Elemente in zwei Listen aus |
klar | Löschen Sie gültige Elemente in der Liste |
void list_test5() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); //头插 lt.push_front(0); //尾插 lt.push_back(5); //头删 lt.pop_front(); //尾删 lt.pop_back(); //pos位置插入 list<int>::iterator lit = lt.begin(); ++lit; lt.insert(lit, 30); //在pos位置插入n个数据 --lit; lt.insert(lit, 2, 10); //迭代器区间插入 vector<int> v = { 10,20 }; ++lit; lt.insert(lit, v.begin(), v.end()); //范围for for (auto e : lt) { cout << e << " "; } cout << endl; }
void list_test6() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); list<int>::iterator lit1 = lt.begin(); //删除pos位置 lt.erase(lit1); //删除一段迭代器区间 lt.erase(lt.begin(), lt.end()); //范围for for (auto e : lt) { cout << e << " "; } cout << endl; }
void list_test7() { list<int> lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); list<int> lt2; lt2.push_back(4); lt2.push_back(3); lt2.push_back(2); lt2.push_back(1); //交换 lt1.swap(lt2); //清理 lt1.clear(); lt2.clear(); }
3. Der Iterator der Liste ist ungültig
Wie bereits erwähnt, kann der Iterator vorübergehend als einem Zeiger ähnlich verstanden werden.Der Ausfall eines Iterators bedeutet, dass der Knoten, auf den der Iterator zeigt, ungültig ist, d. h. Der Knoten wurde gelöscht. . Da die zugrunde liegende Struktur der Liste eine bidirektionale zirkulär verknüpfte Liste mit dem Kopfknoten ist, führt das Einfügen in die Liste nicht dazu, dass der Iterator der Liste fehlschlägt. Es wird nur ungültig gemacht, wenn es gelöscht wird, und nur der Iterator, der auf den gelöschten Knoten zeigt, wird ungültig, andere Iteratoren sind nicht betroffen.
(Spezifische Details werden während der Simulationsimplementierung erläutert)void list_test8() { list<int> lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); auto lit = lt1.begin(); while (lit != lt1.end()) { lt1.erase(lit); // erase()函数执行后,it所指向的节点已被删除, // 因此it无效,在下一次使用it时,必须先给其赋值 lit++; } }
Korrigierter Text:
void list_test8() { list<int> lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); auto lit = lt1.begin(); while (lit != lt1.end()) { lit = lt1.erase(lit); //或者 //lt1.erase(lit++); lit++; } }
Freunde und Jungs, gute Zeiten sind immer kurz. Unser Austausch in dieser Ausgabe endet hier. Wenn Sie wissen möchten, was als nächstes passiert, hören Sie sich bitte die nächste Folge an~. Vergessen Sie nicht, Sie nach dem Lesen wertzuschätzen. Vielen Dank dafür Ihre Unterstützung!