Inhaltsverzeichnis
Die unterste Ebene der Liste ist eigentlich eine doppelt verknüpfte Listenstruktur
Verwendung der Liste
Konstruktor- und Zuweisungsüberladung
Konstrukteur | veranschaulichen |
---|---|
Liste() | Keine Parameterkonstruktion |
Liste (size_type n, const value_type& val = value_type()) | Die erstellte Liste enthält n Elemente mit dem Wert val |
Liste (const list& x) | Konstruktor kopieren |
Liste (InputIterator zuerst, InputIterator zuletzt) | Erstellt eine Liste mit Elementen im Bereich [erster, letzter] |
Der Konstruktor wird genauso verwendet wie der vorherige Container
void test1()
{
list<int> lt1;//无参构造
list<int> lt2(10, 1);//1,1,1,1,1,1,1,1,1,1
list<int> lt3(lt2);//拷贝构造
list<int> lt4(lt2.begin(), lt2.end());
}
Überlastung der Aufgaben
list& operator= (const list& x);
void test1()
{
list<int> lt1;//无参构造
list<int> lt2(10, 1);//1,1,1,1,1,1,1,1,1,1
list<int> lt3(lt2);//拷贝构造
list<int> lt4(lt2.begin(), lt2.end());
list<int> lt5;
lt5 = lt4;//赋值重载
}
Iterator (am wichtigsten)
Es gibt drei Arten von Iteratoren: Einweg-Iterator, Zwei-Wege-Iterator und Zufallsiterator.
Einweg-Iterator: unterstützt ++. Beispielsweise ist der Iteratortyp „forward_list“ und „hash“ ein Einweg-Iterator.
Bidirektionaler Iterator: unterstützt ++, - – Der Iteratortyp „list“, „map“ und „set“ ist beispielsweise Zwei-Wege-Iterator.
Zufälliger Iterator: Unterstützt ++, - -, +, - Der Iteratortyp vector, string, deque ist beispielsweise ein zufälliger Iterator
Zufällige Iteratoren können als spezielle bidirektionale Iteratoren betrachtet werden, und bidirektionale Iteratoren können als spezielle unidirektionale Iteratoren betrachtet werden
Der Iterator der Liste unterscheidet sich vector
von dem der Liste. Der Typ des Iterators wird durch die zugrunde liegende Struktur des Containers bestimmt.string
vector
Die unterste Ebene von und string
ist kontinuierlich, daher sind ihre Iteratoren tatsächlich Zeiger, sie unterstützen also ++, –, +, - und der Typ ist ein zufälliger Iterator
Die list
untere Ebene ist diskontinuierlich und die vordere und hintere Ebene sind durch Zeiger miteinander verbunden, sodass ihr Iterator kein Zeiger ist (eigentlich ist der Zeiger gekapselt). Nach der Kapselung unterstützt der Iterator ++, - - und der Typ ist Single zum Iterator
Für diejenigen, die nicht unterstützt werden
+
,-
liegt der Grund für die Kapselung darin, dassit.begin()+5
die Effizienz zu gering ist und C++ sie nicht unterstützt.
Der Iterator der Liste unterstützt den Iterator im Vektor nicht it.begin()+5
. Wenn Sie es so schreiben, wird ein Fehler gemeldet.
Unterstützt nur ++
,--
void test2()
{
list<int> lt{
1,2,3,4,5,6 };
lt.begin()--;
lt.begin()++;
}
list
Wenn Sie den Iterator wie vector
in it.begin()+5
um mehrere Positionen verschieben möchten , können Sie nur Folgendes tun:
void test2()
{
list<int> lt{
1,2,3,4,5,6 };
list<int>::iterator it = lt.begin();
for (size_t i = 0; i < 5; i++)
{
++it;
}
}
Im Übrigen list
unterstützen Iteratoren auch die vorherigen Funktionen und ihre Verwendung ist dieselbe.
Kapazitätsbezogen
leer
bool empty() const;
Stellen Sie fest, ob der Behälter leer ist
Größe
size_type size() const;
Gibt die Anzahl der Elemente im Container zurück
Einfügen und Löschen
list
Da es sich um eine bidirektionale zirkulär verknüpfte Liste handelt, ist die Effizienz des Einfügens von Köpfen, Löschens von Köpfen, Einfügen von Enden und Löschen von Enden sehr hoch, sodass diese Vorgänge in der Liste unterstützt werden
Funktion | veranschaulichen |
---|---|
void push_front (const value_type& val); | Fügen Sie vor dem ersten Element der Liste ein Element mit dem Wert val ein |
void pop_front(); | Löschen Sie das erste Element in der Liste |
void push_back (const value_type& val); | Fügen Sie am Ende der Liste ein Element mit dem Wert val ein |
void pop_back(); | Löschen Sie das letzte Element in der Liste |
void test3()
{
list<int> lt{
1,2,3,4,5,6 };
lt.push_back(10);
lt.push_front(0);
lt.pop_back();
lt.pop_front();
}
einfügen
iterator insert (iterator position, const value_type& val);
void insert (iterator position, size_type n, const value_type& val);
template <class InputIterator>
void insert (iterator position, InputIterator first, InputIterator last);
insert
Die Operation vector
ist dieselbe wie in, dies insert
führt jedoch nicht zum Ausfall des Iterators
. Da das Einfügen der verknüpften Liste erweitert werden muss, zeigt der Iterator auf einen bestimmten Knoten. Nach dem Einfügen zeigt der Iterator immer noch auf den ursprünglichen Knoten. was den Fehler nicht verursacht.
löschen
iterator erase (iterator position);
iterator erase (iterator first, iterator last);
erase
Die Operation vector
ist die gleiche wie in. Dadurch erase
wird der Iterator ungültig.
Der Iterator zeigt auf einen bestimmten Knoten. Nach dem Löschen dieses Knotens wird der Iterator ungültig.
Elementmanipulation
umkehren
void reverse();
Dies reverse
ist list
eine Funktion, die mit der Klasse geliefert wird und deren Funktion darin besteht, die verknüpfte Liste umzukehren.
Es <algorithm>
gibt auch eine reverse
Funktion
reverse
, bei der der Iteratortyp ein bidirektionaler Iterator ist und der Iteratortyp list ein bidirektionaler Iterator ist, sodass list auch <algorithm>
in verwendet werden kannreverse
void test4()
{
list<int> lt{
1,2,3,4,5,6 };
lt.reverse();
reverse(lt.begin(), lt.end());
}
Sortieren
void sort();
Die Funktion ist das Sortieren. Die unterste Ebene ist, dass
<algorithm>
es sort
Funktionen beim Zusammenführen gibt. Wenn Sie jedoch für Listen sortieren möchten, können Sie nur die Funktionen list
in der Bibliothek verwenden sort
. Sie können die Funktionen <algorithm>
in der Bibliothek nicht verwenden.sort
Da der Iteratortyp der Liste ein bidirektionaler Iterator und der <algorithm>
Parameter- sort
Iteratortyp ein Zufallsiterator ist, kann die Funktion <algorithm>
in der Liste nicht verwendet werden sort
.
Tatsächlich bedeutet es hier nicht viel , da es weniger effizient ist sort
als die <algorithm>
mittlere Ebene (die unterste Ebene in der Mitte verwendet Zusammenführung und die mittlere verwendet schnelle Sortierung). Die einzige Bedeutung ist: Bequemlichkeit. Wenn die Wenn die Datenmenge gering ist, können Sie Aufnahmen machen, aber wenn die Datenmenge nicht mehr groß ist, verwenden Sie sie nichtsort
list
sort
<algorithm>
sort
list
sort
Wenn Sie sortieren möchten, können Sie list
die Daten in vector
die Mitte kopieren, dann sortieren und die Daten nach dem Sortieren in die Mitte kopieren vector
.list
void test5()
{
list<int> lt{
5,7,3,9,1,0,4,7,8,9,4, };
vector<int> v;
//将数据从list拷贝到vector
for (auto e : lt)
{
v.push_back(e);
}
//在vector中排序
reverse(v.begin(), v.end());
//再把数据从vector拷贝到list中
for (auto e : v)
{
lt.push_back(e);
}
}
einzigartig
void unique();
Die Funktion besteht darin, Duplikate zu deduplizieren, sie muss jedoch zuerst sortiert werden
void test6()
{
list<int> lt{
2,6,5,2,2,2,2};
lt.sort();
lt.unique();// 5,6
}
entfernen
void remove (const value_type& val);
Die Funktion von Remove besteht darin, zunächst alle val
Speicherorte zu finden und dann erase
alle zu entfernenval
void test6()
{
list<int> lt{
1,2,3,4,5,6,6,7,8};
//移除元素6
lt.remove(6);//1,2,3,4,5,7,8
}
spleißen
void splice (iterator position, list& x);
void splice (iterator position, list& x, iterator i);
void splice (iterator position, list& x, iterator first, iterator last);
Die Rolle des Spleißes besteht darin, Knoten zu übertragen
void splice (iterator position, list& x)
, überträgtx
alle Elemente in der verknüpften Liste an dieposition
Positionvoid splice (iterator position, list& x, iterator i)
, um das Element an Positionx
in der verknüpften Liste an Position zu übertrageni
position
void splice (iterator position, list& x, iterator first, iterator last)
Übertragenx
Sie die Elemente in [first, last) in der verknüpften Liste anposition
die Position
void test7()
{
list<int> lt1{
1,2,3,4,5,6,7 };
list<int> lt2{
0,0 };
lt2.splice(++lt2.begin(), lt1);
for (auto e : lt1)
{
cout << e << " ";
}//lt1中的元素转移空了
cout << endl;
for (auto e : lt2)
{
cout << e << " ";
}//0 1 2 3 4 5 6 7 0
cout << endl;
list<int> lt3{
1,2,3,4,5,6,7 };
list<int> lt4{
0,0 };
lt4.splice(++lt4.begin(), lt3, ++lt3.begin());
for (auto e : lt3)
{
cout << e << " ";
}//1 3 4 5 6 7
cout << endl;
for (auto e : lt4)
{
cout << e << " ";
}//0 2 0
cout << endl;
list<int> lt5{
1,2,3,4,5,6,7 };
list<int> lt6{
0,0 };
lt6.splice(++lt6.begin(), lt5,++++lt5.begin(), --lt5.end());
for (auto e : lt5)
{
cout << e << " ";
}//1 2 7
cout << endl;
for (auto e : lt6)
{
cout << e << " ";
}//0 3 4 5 6 0
cout << endl;
}