List vs LinkedList in C#: Wann nutzt du was?
Du sitzt in deiner IHK-Abschlussprüfung (oder in der Vorlesung „Algorithmen und Datenstrukturen") und die Aufgabe lautet: Speichere 10.000 Kundendaten und füge regelmäßig neue Elemente am Anfang ein. Nimmst du jetzt `List<T>` oder `LinkedList<T>`? Genau an dieser Frage - List oder LinkedList in C# - scheitern viele Auszubildende, Studenten und Berufseinsteiger. Dabei ist der Unterschied schnell verstanden, wenn du weißt, wie beide Datenstrukturen intern funktionieren. Und auch im ersten Job...
Von Marcel Schmidtpeter 24. Aug. 2026
Du sitzt in deiner IHK-Abschlussprüfung (oder in der Vorlesung „Algorithmen und Datenstrukturen") und die Aufgabe lautet: Speichere 10.000 Kundendaten und füge regelmäßig neue Elemente am Anfang ein. Nimmst du jetzt `List<T>` oder `LinkedList<T>`? Genau an dieser Frage - List oder LinkedList in C# - scheitern viele Auszubildende, Studenten und Berufseinsteiger. Dabei ist der Unterschied schnell verstanden, wenn du weißt, wie beide Datenstrukturen intern funktionieren. Und auch im ersten Job gilt: Wer begründen kann, warum er welche Collection nutzt, punktet in der Code Review.
Kurz zu den Kürzeln, die gleich öfter auftauchen: O(1) heißt konstante Zeit - unabhängig davon, wie viele Elemente drin sind. O(n) heißt: Die Dauer wächst mit der Anzahl der Elemente.
Was ist eine List in C#?
Die `List<T>` ist eine typsichere Collection, die intern von einem Array unterstützt wird - sie wächst automatisch, wenn Elemente hinzukommen. Das `T` steht für den Typ der Elemente, also z. B. `List<int>` oder `List<string>`.
Stell dir ein Regal mit durchnummerierten Fächern vor. Jedes Fach hat eine Nummer, deshalb kannst du sofort auf Fach 47 zugreifen, ohne die vorherigen Fächer anzusehen. Genau so funktioniert der Zugriff per Index: `liste[47]` ist in konstanter Zeit (O(1)) erledigt.
Ist das Regal voll, kauft die `List<T>` ein neues, größeres Regal (typischerweise doppelt so groß) und räumt alles um. Dieses Umbauen kostet Zeit - deshalb spricht man von amortisiert O(1) beim `Add` am Ende. Details findest du in der offiziellen Microsoft-Dokumentation zur `List<T>`-Klasse.
Was ist eine LinkedList in C#?
Die `LinkedList<T>` ist eine doppelt verkettete Liste: Jedes Element steckt in einem `LinkedListNode<T>`, der neben dem Wert zwei Referenzen speichert - eine zum vorherigen und eine zum nächsten Knoten.
Hier passt eine andere Alltagsanalogie: Denk an eine Schnur mit aufgefädelten Perlen. Willst du die 50. Perle haben, musst du von vorne mitzählen. Dafür kannst du eine neue Perle an beliebiger Stelle einfügen, sobald du sie gefunden hast - du verknotest einfach nur die Schnur an einer Position. Verschieben musst du nichts. Mehr Details liefert die Microsoft-Dokumentation zur `LinkedList<T>`-Klasse.
Merke: `List<T>` = schnelle Zugriffe per Index, langsames Einfügen in der Mitte. `LinkedList<T>` = kein Indexzugriff, dafür blitzschnelles Einfügen und Entfernen an bereits bekannten Knoten.
List vs. LinkedList im direkten Vergleich
Diese Tabelle zeigt dir die wichtigsten Unterschiede auf einen Blick:
Eigenschaft | `List<T>` | `LinkedList<T>` |
Interner Aufbau | dynamisches Array | doppelt verkettete Knoten |
Zugriff per Index (`liste[i]`) | ja, O(1) | nicht möglich |
`Add` am Ende | O(1) amortisiert | O(1) |
Einfügen am Anfang | O(n) - alle Elemente rücken | O(1) |
Einfügen in der Mitte (Knoten bekannt) | O(n) | O(1) |
Suche (`Contains`, `Find`) | O(n) | O(n) |
Speicherbedarf | kompakt | höher (zwei Referenzen pro Element) |
Implementiert `IList<T>` | ja | nein |
Beide implementieren `IEnumerable<T>`, du kannst also beide mit `foreach` durchlaufen. Wie das genau funktioniert, erklären wir im Artikel zu IEnumerable und foreach in C#. Die theoretischen Grundlagen findest du auch in unserem Überblick zu Datenstrukturen: Array, Liste, Stack & Queue.
Wann nutzt du List, wann LinkedList in C#?
Kernantwort: In über 90 % der Fälle ist `List<T>` die richtige Wahl. `LinkedList<T>` lohnt sich fast nur bei sehr vielen Einfüge- oder Löschoperationen am Anfang oder an bereits bekannten Knoten.
Warum ist `List<T>` der Standard? Weil Indexzugriff, Iteration und `Add` am Ende die häufigsten Operationen im Alltag sind - und da gewinnt die `List<T>` fast immer. Auch der Speicherverbrauch spricht für sie, weil `LinkedList<T>` pro Element zwei zusätzliche Referenzen mit sich herumschleppt.
`LinkedList<T>` lohnt sich in diesen Situationen:
Sehr viele Einfüge- oder Löschoperationen am Anfang der Sammlung
Einfügen und Entfernen an Positionen, die du als Knoten bereits kennst - z. B. wenn du beim Durchlaufen der Liste merkst: „Genau hier muss was rein"
Wenn du häufig sowohl am Anfang als auch am Ende arbeitest (`AddFirst`, `AddLast`, `RemoveFirst`, `RemoveLast`)
Achtung, häufige Falle: Die O(1)-Einfügeoperation nützt dir nichts, wenn du die Einfügeposition erst suchen musst. Die Suche kostet O(n) - und damit ist der Geschwindigkeitsvorteil oft dahin.
Anders sieht es aus, wenn du sowieso durch die ganze Liste iterierst und dabei einfügst oder löschst - dann sucht niemand extra, und `LinkedList<T>` kann tatsächlich schneller sein. Sei ehrlich mit dir: Solche Fälle sind in der Praxis selten.
Praxisbeispiel: Einfügen am Anfang im Vergleich
Hier ein vollständiges, lauffähiges Programm, das beide Varianten misst. Die `Stopwatch`-Klasse stammt aus dem Namespace `System.Diagnostics`:
using System;
using System.Collections.Generic;
using System.Diagnostics;
class Program
{
static void Main()
{
const int anzahl = 100_000;
// List: Insert(0, ...) verschiebt bei jedem Aufruf alle Elemente
var liste = new List<int>();
var uhr = Stopwatch.StartNew();
for (int i = 0; i < anzahl; i++)
{
liste.Insert(0, i);
}
uhr.Stop();
Console.WriteLine("List Insert am Anfang: " + uhr.ElapsedMilliseconds + " ms");
// LinkedList: AddFirst fuegt immer nur einen Knoten vorne an
var kette = new LinkedList<int>();
uhr = Stopwatch.StartNew();
for (int i = 0; i < anzahl; i++)
{
kette.AddFirst(i);
}
uhr.Stop();
Console.WriteLine("LinkedList AddFirst: " + uhr.ElapsedMilliseconds + " ms");
}
}Auf einem üblichen Entwicklungsrechner siehst du einen deutlichen Unterschied: Die `List<T>` braucht für das Einfügen am Anfang spürbar länger, während die `LinkedList<T>` nahezu konstant schnell bleibt. Probier es aus - solche Messungen bringen dir das Thema näher als jede Theorie.
Und so sieht der gezielte Einsatz von Knoten aus:
var playlist = new LinkedList<string>();
playlist.AddLast("Song A");
playlist.AddLast("Song B");
playlist.AddLast("Song C");
// Neuen Song direkt nach "Song B" einfuegen
// Achtung: Find sucht linear, kostet also O(n)
LinkedListNode<string> knotenB = playlist.Find("Song B");
playlist.AddAfter(knotenB, "Song B (Remix)");
foreach (string titel in playlist)
{
Console.WriteLine(titel);
}Mehr zu den Knoten findest du in der Microsoft-Dokumentation zu `LinkedListNode<T>`.
Häufige Fehler bei List und LinkedList
Fehler 1: Indexer bei LinkedList verwenden
Der Klassiker - und ein häufiger Prüfungsfehler:
var zahlen = new List<int> { 10, 20, 30 };
Console.WriteLine(zahlen[1]); // OK: 20
var kette = new LinkedList<int>(new[] { 10, 20, 30 });
// Console.WriteLine(kette[1]); // Kompiliert nicht! Kein Indexer vorhanden
Console.WriteLine(kette.First.Next.Value); // 20, aber umstaendlichDie `LinkedList<T>` bietet schlicht keinen Indexer, weil sie dafür die komplette Kette durchlaufen müsste.
Fehler 2: Geschwindigkeit ohne die Suche bewerten
Viele lernen „LinkedList einfügen = O(1)" und wunder sich, dass ihr Code langsamer ist als mit `List<T>`. Das Einfügen selbst ist zwar O(1) - aber `Find` oder `Remove(value)` suchen erst einmal linear. Rechne immer Suche plus Einfügen zusammen.
Fehler 3: List ohne Kapazität bei bekannter Größe
Kennst du die ungefähre Anzahl der Elemente, gib die Startkapazität an. Dann vermeidest du mehrfaches Umbauen des internen Arrays:
// Schlecht: viele interne Umkopier-Vorgaenge
var langsam = new List<int>();
// Besser: Kapazitaet gleich mitgeben
var schnell = new List<int>(capacity: 100_000);Übungstipp
Baue eine kleine To-Do-Verwaltung: Aufgaben, die ständig vorne priorisiert (`AddFirst`) und erledigte entfernt werden (`RemoveFirst`) - ein klassischer Fall für `LinkedList<T>`. Implementiere dieselbe Logik anschließend mit `List<T>` und miss beide Varianten mit `Stopwatch`. Notiere dir danach in zwei Sätzen, warum welche Variante gewonnen hat. Genau diese Begründung wird dir in Prüfung, Seminararbeit oder Code Review abverlangt.
FAQ: Häufige Fragen zu List und LinkedList
Ist die C# List intern ein Array?
Ja. `List<T>` kapselt ein Array und vergrößert es automatisch (meist verdoppelt sie die Kapazität), wenn der Platz nicht reicht. Deshalb ist der Indexzugriff O(1) und Einfügen in der Mitte O(n).
Warum hat LinkedList keinen Indexer?
Weil ein Zugriff auf `liste[500]` bedeuten würde, von vorne 500 Knoten durchzuhangeln - also O(n). Die .NET-Designer haben bewusst darauf verzichtet, damit kein falscher Eindruck von Konstantzeit entsteht.
Was ist schneller: List oder LinkedList?
Es kommt auf die Operation an: Indexzugriff und `Add` am Ende gewinnt `List<T>`. Häufiges Einfügen oder Entfernen am Anfang bzw. an bekannten Knoten gewinnt `LinkedList<T>`. Für die Suche sind beide gleich schnell: O(n).
Implementieren beide IList<T>?
Nein. `List<T>` implementiert `IList<T>` (und damit auch den Indexer), `LinkedList<T>` implementiert nur `ICollection<T>` und `IEnumerable<T>`. Das merkst du spätestens, wenn eine Methode `IList<T>` als Parameter verlangt.
Wann nutzt man LinkedList in der Praxis wirklich?
Ehrliche Antwort: selten. Typische Fälle sind Warteschlangen, bei denen man an beiden Enden arbeitet, oder Algorithmen, die beim Durchlaufen gezielt Knoten entfernen. Wenn du nur „vorne rein, hinten raus" brauchst, ist `Queue<T>` oft die passendere Wahl.
Fazit
Bei der Wahl zwischen List und LinkedList in C# gilt: `List<T>` ist dein Standardwerkzeug - array-basiert, indexierbar, speichereffizient und für die allermeisten Alltagssituationen schnell genug. `LinkedList<T>` ist ein Spezialwerkzeug für viele Einfüge- und Löschoperationen an bekannten Knoten, verzichtet dafür aber auf den Indexzugriff. Wer diese Abwägung begründen kann, hat in Prüfung, Studium und Beruf etwas voraus, das viele überspringen.
Wenn du bei C# oder Datenstrukturen noch tiefer einsteigen willst: Bei study-it.education findest du persönliche IT-Nachhilfe, die genau auf Azubis, Studenten und Berufseinsteiger zugeschnitten ist - von Collections bis zur Abschlussprüfung.
Brauchst du jemand, der das mit dir durchgeht?
Statt nochmal lesen: 30 min mit einem Senior-Dev.
Kostenloses Erstgespräch buchen →
Du sitzt in deiner IHK-Abschlussprüfung (oder in der Vorlesung „Algorithmen und Datenstrukturen") und die Aufgabe lautet: Speichere 10.000 Kundendaten und füge regelmäßig neue Elemente am Anfang ein. Nimmst du jetzt `List<T>` oder `LinkedList<T>`? Genau an dieser Frage - List oder LinkedList in C# - scheitern viele Auszubildende, Studenten und Berufseinsteiger. Dabei ist der Unterschied schnell verstanden, wenn du weißt, wie beide Datenstrukturen intern funktionieren. Und auch im ersten Job...
marcel.schmidtpeter@study-it.education →Mehr Lesestoff
C# LINQ filtern und transformieren: Einfach erklärt mit Beispielen
LINQ macht Datenfilterung in C# kinderleicht: Mit Where, Select & Co. filterst und transformierst du Listen in wenigen Zeilen – hier lernst du wie!
C# Nullable einfach erklärt: So vermeidest du NullReferenceExceptions
Nullable-Typen in C# markieren Variablen, die null sein dürfen – und helfen dir, NullReferenceExceptions früh zu erkennen und zu vermeiden.
C# Lambda Expression einfach erklärt: Syntax & Beispiele
Lambda-Ausdrücke in C# verständlich erklärt: Syntax, Func & Action sowie praxisnahe Beispiele für Azubis, Studenten und Berufseinsteiger.