C++ Datenstrukturen
C++ bietet eine Vielzahl von Datenstrukturen, von grundlegenden wie Arrays, Strukturen und Klassen bis hin zu fortgeschrittenen STL-Containern wievector、mapundunordered_mapusw.
Im Folgenden werden die häufig verwendeten Datenstrukturen in C++ zusammen mit ihren Eigenschaften und ihrer Verwendung detailliert beschrieben.
1. Array
Arrays sind die grundlegendsten Datenstrukturen und werden verwendet, um eine Menge gleichartiger Daten zu speichern.
Funktionen:
- Feste Größe; nach der Deklaration kann die Größe nicht geändert werden.
- Direkter Elementzugriff mit einer Zeitkomplexität von O(1).
- Geeignet für die Verarbeitung von Sammlungen bekannter Größe mit identischen Elementtypen.
Beispiel
cout << arr[0]; // Erstes Element ausgeben
Vorteile und Nachteile:
- Vorteil: Schnelle Zugriffsgeschwindigkeit, kompakter Speicherverbrauch.
- Nachteile: feste Größe, kann nicht dynamisch erweitert werden, nicht geeignet für Datensätze ungewisser Größe.
2. Struktur
Strukturen ermöglichen die Kombination verschiedener Datentypen zu einem benutzerdefinierten Datentyp.
Funktionen:
- Kann Membervariablen unterschiedlicher Typen enthalten.
- Bietet eine grundlegende Kapselung von Daten, jedoch mit begrenzter Funktionalität.
Beispiel:
Beispiel
string name;
int age;
};
Person p = {"Alice", 25};
cout << p.name << endl; // Ausgabe Alice
3. Klasse
Klassen sind die Kernstruktur für objektorientierte Programmierung in C++ und ermöglichen die Definition von Membervariablen und Memberfunktionen. Verglichen mitstructÄhnlich, aber leistungsfähiger, mit Unterstützung von Funktionen wie Vererbung, Kapselung und Polymorphie.
Funktionen:
- Kann Membervariablen, Memberfunktionen, Konstruktoren und Destruktoren enthalten.
- Unterstützt objektorientierte Merkmale wie Kapselung, Vererbung und Polymorphie.
Beispiel
private:
string name;
int age;
public:
Person(string n, int a) : name(n), age(a) {}
void printInfo() {
cout << "Name: " << name << ", Alter: " << age << endl;
}
};
Person p("Bob", 30);
p.printInfo(); // Ausgabe: Name: Bob, Alter: 30
4. Verkettete Liste
Eine verkettete Liste ist eine dynamische Datenstruktur, die aus einer Reihe von Knoten besteht, wobei jeder Daten und einen Zeiger auf den nächsten Knoten enthält.
Funktionen:
- Passt seine Größe dynamisch an, Kapazität muss nicht vorab festgelegt werden.
- Einfüge- und Löschoperationen sind effizient, mit einer Zeitkomplexität von O(1) (beim Arbeiten am Kopf oder Ende der Liste).
- Lineare Suche mit einer Zeitkomplexität von O(n).
Beispiel (einfach verkettete Liste)
int data;
Node* next;
};
Node* head = nullptr;
Node* newNode = new Node{10, nullptr};
head = newNode; // Neuen Knoten einfügen
Vorteile und Nachteile:
- Vorteile: dynamische Größe, geeignet für Szenarien mit häufigen Einfügungen und Löschungen.
- Nachteile: ineffizienter wahlfreier Zugriff, nicht so schnell wie direkter Array-Zugriff.
5. Stapel
Ein Stack ist eine Last-In-First-Out-(LIFO)-Datenstruktur, die häufig in Szenarien wie Rekursion und Tiefensuche verwendet wird.
Funktionen:
- Erlaubt nur Einfüge- und Löschoperationen am oberen Ende des Stapels.
- Die Zeitkomplexität ist O(1).
Beispiel
s.push(1);
s.push(2);
cout << s.top(); // Ausgabe 2
s.pop();
Vorteile und Nachteile:
- Vorteil: Einfache Operationen, hohe Effizienz.
- Nachteile: Operationen können nur am oberen Ende ausgeführt werden; der Zugriff auf andere Elemente erfordert das Entfernen des obersten Elements.
6. Warteschlange
Eine Warteschlange ist eine First-In-First-Out-Datenstruktur (FIFO), die häufig in Szenarien wie der Breitensuche und der Aufgabenplanung verwendet wird.
Funktionen:
- Einfügeoperationen erfolgen am Ende der Warteschlange, und Löschoperationen erfolgen am Kopf.
- Die Zeitkomplexität ist O(1).
Beispiel
q.push(1);
q.push(2);
cout << q.front(); // Ausgabe 1
q.pop();
Vorteile und Nachteile:
- Vorteile: Geeignet für Szenarien, die Daten in der Reihenfolge verarbeiten, wie z. B. Aufgabenplanung.
- Nachteil: Kein wahlfreier Zugriff auf Elemente möglich.
7. Doppelendige Warteschlange (Deque)
Eine Deque ermöglicht Einfüge- und Löschoperationen an beiden Enden und kombiniert die Eigenschaften eines Stapels und einer Warteschlange.
Funktionen:
- Ermöglicht Einfügen und Löschen an beiden Enden.
- Die Zeitkomplexität ist O(1).
Beispiel
dq.push_back(1);
dq.push_front(2);
cout << dq.front(); // Ausgabe 2
dq.pop_front();
Vorteile und Nachteile:
- Vorteil: Flexible bidirektionale Operationen.
- Nachteile: größerer Speicherbedarf, geeignet für Szenarien, die häufige Operationen an beiden Enden erfordern.
8. Hash-Tabelle
Eine Hash-Tabelle ist eine Datenstruktur, die Daten über Schlüssel-Wert-Paare speichert und schnelle Such-, Einfüge- und Löschoperationen unterstützt. In C++,unordered_mapEine Implementierung einer Hash-Tabelle.
Funktionen:
- Verwendet eine Hash-Funktion, um Elemente schnell zu lokalisieren, mit einer Zeitkomplexität von O(1).
- Garantiert nicht die Reihenfolge der Elemente.
Beispiel
hashTable["apple"] = 10;
cout << hashTable["apple"]; // Ausgabe 10
Vorteile und Nachteile:
- Vorteile: hohe Effizienz bei Such-, Einfüge- und Löschvorgängen.
- Nachteile: Die Reihenfolge der Elemente kann nicht garantiert werden, und die Leistung verschlechtert sich, wenn Hash-Kollisionen auftreten.
9. Map
mapEs ist ein geordneter Container für Schlüssel-Wert-Paare, implementiert unter Verwendung eines Rot-Schwarz-Baums. Im Vergleich zuunordered_mapanderen, garantiert es die Reihenfolge der Schlüssel, mit Zeitkomplexitäten von O(log n) für Suchen, Einfügen und Löschen.
Funktionen:
- Garantiert, dass die Elemente in der Reihenfolge ihrer Schlüssel angeordnet sind.
- Implementiert unter Verwendung eines binären Suchbaums.
Beispiel
myMap["apple"] = 10;
cout << myMap["apple"]; // Ausgabe 10
Vorteile und Nachteile:
- Vorteile: Elemente sind geordnet, geeignet für Szenarien, in denen Daten in der Reihenfolge verarbeitet werden müssen.
- Nachteil: Geringere operationelle Effizienz als
unordered_mapEtwas niedriger.
10. Set
setEs ist ein geordnetes Set zum Speichern eindeutiger Elemente, das ebenfalls mit einem Rot-Schwarz-Baum implementiert ist. Es stellt sicher, dass Elemente nicht dupliziert und geordnet sind.
Funktionen:
- Garantiert die Eindeutigkeit von Elementen.
- Elemente werden automatisch in aufsteigender Reihenfolge angeordnet.
- Die Zeitkomplexität ist O(log n).
Beispiel
s.insert(1);
s.insert(2);
cout << *s.begin(); // Ausgabe 1
Vorteile und Nachteile:
- Vorteil: Automatische Sortierung und Garantie der Eindeutigkeit.
- Nachteile: Einfüge- und Lösch-Effizienz ist geringer als bei ungeordneten Mengen.
11. Dynamisches Array (Vektor)
vectorEs handelt sich um eine von der C++-Standardbibliothek bereitgestellte Implementierung eines dynamischen Arrays, die ihre Kapazität dynamisch erweitern kann und wahlfreien Zugriff unterstützt.
Funktionen:
- Dynamische Größenanpassung.
- Unterstützt wahlfreien Zugriff mit einer Zeitkomplexität von O(1).
- Wenn die Kapazität nicht ausreicht, wird sie dynamisch erweitert, mit einer amortisierten Zeitkomplexität von O(1).
Beispiel
v.push_back(1);
v.push_back(2);
cout << v[0]; // Ausgabe 1
Vorteile und Nachteile:
- Vorteile: Unterstützt wahlfreien Zugriff und dynamische Erweiterung.
- Nachteile: geringe Effizienz beim Einfügen oder Löschen von Elementen in der Mitte.