Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

การได้ Enumerator วนลูป LinkedList ใน C#

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> - เมื่อไหร่ควรใช้ไหน

OperationLinkedList<T>List<T>
AddFirst/AddLastO(1)O(1) amortized (Last), O(n) (First)
Insert middleO(1) if have node refO(n)
Remove nodeO(1) if have node refO(n)
Access by indexO(n)O(1)
Memory overheadสูง (node objects)ต่ำ (array)
Cache localityแย่ดีมาก

แนวทางปฏิบัติ

  • ส่วนใหญ่ควรใช้ List<T> - เร็วกว่า ความจดจำดีกว่า API ครบครัน
  • ใช้ LinkedList<T> กรณีพิเศษ: insert/delete บ่อยที่กลาง, ต้องการ O(1) remove ด้วย node reference