LinkedList<T>
En LinkedList<T> är en samling noder där varje nod håller ett värde och en pekare till nästa — och i .NET även till föregående — nod. Till skillnad från en lista finns inget underliggande array-block. Du kan lägga till och ta bort element i mitten utan att flytta runt data.
TL;DR
LinkedList<T>är bra när du ofta lägger till eller tar bort element mitt i samlingen.- Slumpmässig åtkomst (
minList[5]) är långsam —O(n). VäljList<T>om du indexerar ofta. - .NET:s
LinkedList<T>är dubbel-länkad — varje nod har bådeNextochPrevious.
Hur den är uppbyggd
[HEAD] → [Data | Prev | Next] → [Data | Prev | Next] → … → [Data | null]En enkel-länkad lista pekar bara framåt. .NET:s variant är dubbel-länkad och kan traverseras i båda riktningar.
Komplexitet
| Operation | LinkedList<T> | List<T> |
|---|---|---|
| Lägg till i början/slutet | O(1) | O(1) (bara slutet) |
| Lägg till i mitten (med nod) | O(1) | O(n) |
| Borttag (med referens) | O(1) | O(n) |
| Hitta via index | O(n) | O(1) |
| Iteration | O(n) | O(n) |
O(1) vid insättning gäller bara när du redan har en referens till noden — att hitta rätt nod kostar O(n).
Exempel: använda LinkedList<T>
var todo = new LinkedList<string>();
todo.AddLast("Koka kaffe");var kodaNode = todo.AddLast("Skriva kod");todo.AddLast("Pusha till GitHub");
// Lägg in något direkt före en känd nod — O(1)todo.AddBefore(kodaNode, "Sätta på spellistan");
// Ta bort noden direkt — O(1)todo.Remove(kodaNode);
foreach (var task in todo){ Console.WriteLine(task);}AddBefore och Remove tar emot LinkedListNode<T> — det är nodreferensen som gör operationerna konstant tid.
Bygg en egen nod
public class Node<T>{ public T Value { get; set; } public Node<T>? Next { get; set; }
public Node(T value) => Value = value;}
public class SinglyLinkedList<T>{ public Node<T>? Head { get; private set; }
public void AddFirst(T value) { var node = new Node<T>(value) { Next = Head }; Head = node; }
public void RemoveFirst() { if (Head is not null) Head = Head.Next; }}En egen implementation ger förståelse för pekare och vad som händer under huven.
När ska du använda LinkedList?
Välj LinkedList<T> när du:
- Bygger undo/redo där du rör dig framåt och bakåt i historiken.
- Implementerar en LRU-cache (flytta senaste elementet till fronten i
O(1)). - Ofta lägger till eller tar bort element mitt i samlingen.
Välj List<T> när du:
- Läser ofta via index.
- Förändrar samlingen sällan men itererar ofta.
- Behöver serialisera till JSON/XML —
LinkedList<T>ger mer verbos output.
Vanliga misstag
- Tappa noder: vid dubbel-länkning måste du uppdatera både
NextochPrevious, annars skapar du noder som aldrig nås. - Ta bort under iteration: spara
current.Nexti en variabel innan du anroparRemove(current). - Indexering:
LinkedList<T>har ingen indexer — behöver dulist[i]regelbundet är fel struktur vald.
Kombinera med Dictionary
En klassisk kombination för LRU-cache:
// Nyckeln ger O(1) till noden, noden ger O(1) flytt i listanvar cache = new Dictionary<string, LinkedListNode<string>>();var order = new LinkedList<string>();Övningar
- Implementera
MoveToFront(LinkedListNode<T>)som flyttar en nod till listans början. - Bygg en musikspellista där du kan stega framåt och bakåt utan att tappa nuvarande position.
- Implementera en enkel LRU-cache med
LinkedList<T>ochDictionary<K, LinkedListNode<T>>.