Jeder kann coden / Programmieren & TicTacToe / C# Einführung
Komplexere Datenstrukturen¶
![]() |
![]() |
Link zur Microsoft Dokumentation Link zum roten Faden auf Miro |
Komplexe Datenstrukturen in C# sind Datenstrukturen, die mehr als einfache Werte (wie int, string, etc.) enthalten und oft mehrere Ebenen oder eine Kombination verschiedener Typen und Strukturen bieten. Hier sind die grundlegenden Typen:
1. Arrays (Wiederholung)¶
- Arrays sind eine Sammlung von Elementen desselben Datentyps, die über einen Index zugegriffen werden können. Sie sind fix in ihrer Größe und sehr effizient für den Zugriff auf die Daten.
- Einfache Arrays:
int[] numbers = new int[5];
- Mehrdimensionale Arrays:
int[,] matrix = new int[3, 3];
- Verzweigte Arrays (Zickzack-Arrays):
int[][] jaggedArray = new int[3][];
- Vorteile: Schneller Zugriff auf Elemente.
- Nachteile: Feste Größe, daher weniger flexibel.
In [ ]:
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(numbers[2]); // Ausgabe: 3
2. Listen (List<T>
)¶
- Listen sind dynamische Arrays und bieten die Möglichkeit, Elemente hinzuzufügen oder zu entfernen. Sie sind viel flexibler als Arrays, da ihre Größe dynamisch angepasst wird.
- Deklaration:
List<int> numbers = new List<int>();
- Methoden:
Add()
,Remove()
,Contains()
,Count
. - Vorteile: Flexibel und einfacher im Handling.
- Nachteile: Im Vergleich zu Arrays geringfügig langsamer beim direkten Zugriff auf große Datenmengen.
In [ ]:
List<string> fruits = new List<string> { "Apple", "Banana", "Cherry" };
fruits.Add("Orange");
Console.WriteLine(fruits[s]);
foreach ( string s in fruits ) {
Console.WriteLine(s); // Ausgabe: Cherry
}
Apple Banana Cherry Orange
3. Wörterbuch (Dictionary<TKey, TValue>
)¶
- Ein Wörterbuch ist eine Sammlung von Schlüssel-Wert-Paaren, bei denen jedes Element einen Schlüssel und einen Wert hat. Es wird verwendet, um Daten schnell anhand eines eindeutigen Schlüssels zu suchen.
- Deklaration:
Dictionary<string, int> ageMap = new Dictionary<string, int>();
- Vorteile: Sehr effizient für schnelle Nachschlageoperationen.
- Nachteile: Schlüssel müssen eindeutig sein und der Schlüssel wird zum Indexieren verwendet.
In [5]:
Dictionary<string, int> ages = new Dictionary<string, int>();
ages["Alice"] = 30;
ages["Bob"] = 25;
Console.WriteLine(ages["Alice"]); // Ausgabe: 30
30
4. Warteschlangen (Queue<T>
)¶
- Warteschlangen sind FIFO (First In, First Out) Datenstrukturen, bei denen das erste hinzugefügte Element auch das erste ist, das entfernt wird.
- Deklaration:
Queue<int> queue = new Queue<int>();
- Methoden:
Enqueue()
fügt ein Element hinzu,Dequeue()
entfernt ein Element. - Vorteile: Ideal für Szenarien, in denen Elemente in einer bestimmten Reihenfolge verarbeitet werden müssen.
- Nachteile: Kein direkter Zugriff auf Elemente in der Mitte der Warteschlange.
In [ ]:
Queue<string> queue = new Queue<string>();
queue.Enqueue("First");
queue.Enqueue("Second");
Console.WriteLine(queue.Dequeue()); // Ausgabe: First
5. Stapel (Stack<T>
)¶
- Stacks sind LIFO (Last In, First Out) Datenstrukturen, bei denen das letzte hinzugefügte Element auch das erste ist, das entfernt wird.
- Deklaration:
Stack<int> stack = new Stack<int>();
- Methoden:
Push()
fügt ein Element hinzu,Pop()
entfernt das oberste Element. - Vorteile: Effizient für Szenarien, in denen der Zugriff auf das zuletzt hinzugefügte Element wichtig ist.
- Nachteile: Kein Zugriff auf Elemente außer auf das oberste.
In [ ]:
Stack<string> stack = new Stack<string>();
stack.Push("Bottom");
stack.Push("Top");
Console.WriteLine(stack.Pop()); // Ausgabe: Top
6. Mengen (HashSet<T>
)¶
- Ein HashSet speichert eine Sammlung von eindeutigen Elementen und wird häufig verwendet, um die Existenz eines bestimmten Wertes schnell zu überprüfen.
- Deklaration:
HashSet<int> uniqueNumbers = new HashSet<int>();
- Vorteile: Schnelle Überprüfung auf das Vorhandensein eines Elements.
- Nachteile: Keine Duplikate erlaubt, und die Elemente haben keine bestimmte Reihenfolge.
In [ ]:
HashSet<int> uniqueNumbers = new HashSet<int> { 1, 2, 3, 3 };
uniqueNumbers.Add(4);
Console.WriteLine(uniqueNumbers.Contains(3)); // Ausgabe: True
7. Verbundene Listen (LinkedList<T>
)¶
- LinkedLists bestehen aus Knoten, die Verweise auf das nächste und, bei doppelt verketteten Listen, das vorherige Element enthalten. Diese Struktur ermöglicht eine dynamische Größe und das Einfügen oder Entfernen von Elementen an beliebiger Stelle.
- Deklaration:
LinkedList<int> linkedList = new LinkedList<int>();
- Vorteile: Flexibler als Arrays und Listen für Einfüge-/Löschoperationen.
- Nachteile: Langsamer bei sequentiellem Zugriff im Vergleich zu Arrays oder Listen.
In [ ]:
LinkedList<string> linkedList = new LinkedList<string>();
linkedList.AddLast("First");
linkedList.AddLast("Second");
linkedList.AddFirst("Zeroth");
Console.WriteLine(linkedList.First.Value); // Ausgabe: Zeroth
8. Bäume¶
- Bäume sind hierarchische Datenstrukturen, die eine Sammlung von Elementen in Eltern-Kind-Beziehungen organisieren.
- Typische Anwendungen sind binäre Bäume, AVL-Bäume, B-Bäume oder N-Bäume. In C# können diese als Klassen modelliert werden.
- Deklaration eines binären Baums erfolgt durch Erstellung von Knoten-Klassen mit
left
undright
Verweisen. - Vorteile: Effizient für hierarchische Daten und schnelle Suchen.
- Nachteile: Komplex in der Implementierung und Pflege.
In [ ]:
class TreeNode {
public int Value;
public TreeNode Left;
public TreeNode Right;
public TreeNode(int value) { Value = value; }
}
TreeNode root = new TreeNode(1);
root.Left = new TreeNode(2);
root.Right = new TreeNode(3);
Console.WriteLine(root.Left.Value); // Ausgabe: 2
9. Graphen¶
- Graphen sind Netzwerke von Knoten, die durch Kanten verbunden sind. Sie werden verwendet, um Beziehungen darzustellen, wie z.B. soziale Netzwerke oder Routen.
- In C# werden Graphen typischerweise durch
Dictionary<TKey, List<TValue>>
oder benutzerdefinierte Klassen für Knoten und Kanten implementiert. - Vorteile: Ideal für die Darstellung und Bearbeitung von Netzwerken und Beziehungen.
- Nachteile: Komplex in der Implementierung und erfordern spezielle Algorithmen zur effizienten Navigation.
In [ ]:
class Graph {
public Dictionary<string, List<string>> AdjacencyList = new Dictionary<string, List<string>>();
public void AddEdge(string node, string neighbor) {
if (!AdjacencyList.ContainsKey(node)) {
AdjacencyList[node] = new List<string>();
}
AdjacencyList[node].Add(neighbor);
}
}
Graph graph = new Graph();
graph.AddEdge("A", "B");
graph.AddEdge("A", "C");
Console.WriteLine(string.Join(", ", graph.AdjacencyList["A"])); // Ausgabe: B, C
Jede dieser Strukturen kann je nach Anforderungen an Leistung, Speicherbedarf und die Art der Daten in einem bestimmten Szenario vorteilhaft sein.