LinkedList<T> มีเมธอด GetEnumerator() คืน LinkedList<T>.Enumerator (struct) สำหรับวนลูปผ่านโหนดทีละตัว รองรับ MoveNext() และ Current ตาม pattern มาตรฐาน
ตัวอย่างโค้ดที่ 1: ใช้ Enumerator โดยตรง
using System;
using System.Collections.Generic;
public class Demo
{
public static void Main()
{
LinkedList list = new LinkedList();
list.AddLast("A");
list.AddLast("B");
list.AddLast("C");
list.AddLast("D");
list.AddLast("E");
list.AddLast("F");
list.AddLast("G");
list.AddLast("H");
list.AddLast("I");
list.AddLast("J");
Console.WriteLine("Count of nodes = " + list.Count);
Console.WriteLine("Elements in LinkedList... (Enumerator iterating through LinkedList)");
LinkedList.Enumerator demoEnum = list.GetEnumerator();
while (demoEnum.MoveNext())
{
string res = demoEnum.Current;
Console.WriteLine(res);
}
}
}
ผลลัพธ์
Count of nodes = 10
Elements in LinkedList... (Enumerator iterating through LinkedList)
A
B
C
D
E
F
G
H
I
J
ตัวอย่างโค้ดที่ 2: หลาย LinkedList และ Reference Equality
using System;
using System.Collections.Generic;
public class Demo
{
public static void Main(string[] args)
{
LinkedList list1 = new LinkedList();
list1.AddLast("One");
list1.AddLast("Two");
list1.AddLast("Three");
list1.AddLast("Four");
list1.AddLast("Five");
Console.WriteLine("Elements in LinkedList1...");
foreach (string res in list1)
{
Console.WriteLine(res);
}
LinkedList list2 = new LinkedList();
list2.AddLast("India");
list2.AddLast("US");
list2.AddLast("UK");
list2.AddLast("Canada");
list2.AddLast("Poland");
list2.AddLast("Netherlands");
Console.WriteLine("Elements in LinkedList2... (Enumerator iterating through LinkedList2)");
LinkedList.Enumerator demoEnum = list2.GetEnumerator();
while (demoEnum.MoveNext())
{
string res = demoEnum.Current;
Console.WriteLine(res);
}
LinkedList list3 = new LinkedList();
list3 = list2; // Reference assignment
Console.WriteLine("Is LinkedList3 equal to LinkedList2? = " + list3.Equals(list2));
}
}
ผลลัพธ์
Elements in LinkedList1...
One
Two
Three
Four
Five
Elements in LinkedList2... (Enumerator iterating through LinkedList2)
India
US
UK
Canada
Poland
Netherlands
Is LinkedList3 equal to LinkedList2? = True
Enumerator ของ LinkedList<T>
- เป็น struct (value type) - ไม่กดดัน GC
- รองรับ
MoveNext(),Current,Reset(),Dispose() - เดินจาก Head ไป Tail (forward only)
foreachใช้ Enumerator นี้ภายในโดยอัตโนมัติ
การเข้าถึงโหนดโดยตรง (Advanced)
var node = list.First;
while (node != null)
{
Console.WriteLine(node.Value);
node = node.Next; // หรือ node.Previous เพื่อย้อนกลับ
}
LinkedList vs List<T> - เมื่อไหร่ควรใช้ไหน
| Operation | LinkedList<T> | List<T> |
|---|---|---|
| AddFirst/AddLast | O(1) | O(1) amortized (Last), O(n) (First) |
| Insert middle | O(1) if have node ref | O(n) |
| Remove node | O(1) if have node ref | O(n) |
| Access by index | O(n) | O(1) |
| Memory overhead | สูง (node objects) | ต่ำ (array) |
| Cache locality | แย่ | ดีมาก |
แนวทางปฏิบัติ
- ส่วนใหญ่ควรใช้
List<T>- เร็วกว่า ความจดจำดีกว่า API ครบครัน - ใช้
LinkedList<T>กรณีพิเศษ: insert/delete บ่อยที่กลาง, ต้องการ O(1) remove ด้วย node reference