ฉันเห็นว่าคำตอบที่เสนอนั้นมุ่งเน้นไปที่ประสิทธิภาพ บทความด้านล่างนี้ไม่ได้ให้ข้อมูลใหม่เกี่ยวกับประสิทธิภาพ แต่จะอธิบายถึงกลไกพื้นฐาน โปรดทราบว่ามันไม่ได้มุ่งเน้นไปที่สามCollection
ประเภทที่กล่าวถึงในคำถาม แต่จะกล่าวถึงประเภททั้งหมดของSystem.Collections.Generic
เนมสเปซ
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
สารสกัด:
พจนานุกรม <>
พจนานุกรมน่าจะเป็นคลาสคอนเทนเนอร์ที่ใช้ร่วมกันมากที่สุด พจนานุกรมเป็นชั้นที่เร็วที่สุดสำหรับการค้นหาเชื่อมโยง / แทรก / ลบเพราะมันใช้ตารางแฮชภายใต้ครอบคลุม เนื่องจากมีการแฮชคีย์ประเภทคีย์ควรใช้ GetHashCode () และ Equals () อย่างถูกต้องอย่างเหมาะสมหรือคุณควรให้ IEqualityComparer ภายนอกกับพจนานุกรมเกี่ยวกับโครงสร้าง เวลาแทรก / ลบ / ค้นหาของรายการในพจนานุกรมคือเวลาคงที่แบบตัดจำหน่าย - O (1) - ซึ่งหมายความว่าไม่ว่าพจนานุกรมจะใหญ่แค่ไหนก็ตามเวลาที่ใช้ในการค้นหาบางสิ่งก็ยังคงค่อนข้างคงที่ สิ่งนี้เป็นที่ต้องการอย่างมากสำหรับการค้นหาความเร็วสูง ข้อเสียเพียงอย่างเดียวคือพจนานุกรมโดยธรรมชาติของการใช้ตารางแฮชนั้นไม่มีการเรียงลำดับดังนั้นคุณจะไม่สามารถตัดผ่านรายการในพจนานุกรมในการสั่งซื้อ
เรียงลำดับ
SortedDictionary คล้ายกับ Dictionary ในการใช้งาน แต่แตกต่างกันมากในการนำไปใช้งาน SortedDictionary ใช้ต้นไม้ไบนารีภายใต้ครอบคลุมในการรักษารายการในการสั่งซื้อโดยกุญแจสำคัญ อันเป็นผลมาจากการเรียงลำดับประเภทที่ใช้สำหรับคีย์จะต้องใช้ IComparable อย่างถูกต้องเพื่อให้เรียงลำดับคีย์ได้อย่างถูกต้อง พจนานุกรมที่เรียงลำดับจะใช้เวลาในการค้นหาเล็กน้อยเพื่อความสามารถในการรักษารายการตามลำดับดังนั้นเวลาแทรก / ลบ / ค้นหาในพจนานุกรมที่เรียงลำดับจึงเป็นลอการิทึม - O (log n) โดยทั่วไปเมื่อใช้เวลาลอการิทึมคุณสามารถเพิ่มขนาดของคอลเล็กชันได้เป็นสองเท่าและจะต้องทำการเปรียบเทียบเพิ่มเติมเพียงครั้งเดียวเพื่อค้นหารายการ ใช้ SortedDictionary เมื่อคุณต้องการค้นหาอย่างรวดเร็ว แต่ยังต้องการให้สามารถรักษาคอลเลกชันตามลำดับด้วยคีย์
SortedList <>
SortedList คือคลาสคอนเทนเนอร์ที่เชื่อมโยงแบบเรียงลำดับอื่น ๆ ในคอนเทนเนอร์ทั่วไป อีกครั้งหนึ่งที่ SortedList เช่น SortedDictionary, ใช้กุญแจสำคัญในการจัดเรียงคู่คีย์ค่า ไม่เหมือนกับ SortedDictionary อย่างไรก็ตามรายการใน SortedList จะถูกจัดเก็บเป็นอาร์เรย์ของรายการที่เรียงลำดับ. ซึ่งหมายความว่าการแทรกและการลบเป็นแบบเชิงเส้น - O (n) - เนื่องจากการลบหรือเพิ่มรายการอาจเกี่ยวข้องกับการเลื่อนรายการทั้งหมดขึ้นหรือลงในรายการ อย่างไรก็ตามเวลาในการค้นหาคือ O (log n) เนื่องจาก SortedList สามารถใช้การค้นหาแบบไบนารีเพื่อค้นหารายการใด ๆ ในรายการโดยใช้คีย์ แล้วทำไมคุณถึงอยากทำเช่นนี้? คำตอบก็คือถ้าคุณจะโหลด SortedList ขึ้นหน้าการแทรกจะช้าลง แต่เนื่องจากการจัดทำดัชนีอาร์เรย์เร็วกว่าการติดตามลิงก์วัตถุการค้นหาจึงเร็วกว่า SortedDictionary เล็กน้อย อีกครั้งฉันจะใช้สิ่งนี้ในสถานการณ์ที่คุณต้องการการค้นหาอย่างรวดเร็วและต้องการรักษาคอลเล็กชันตามลำดับของคีย์และในกรณีที่การแทรกและการลบหายาก
สรุปเบื้องต้นของขั้นตอนพื้นฐาน
คำติชมยินดีเป็นอย่างยิ่งเพราะฉันแน่ใจว่าฉันทำทุกอย่างไม่ถูกต้อง
n
อาร์เรย์ทั้งหมดมีขนาด
- อาร์เรย์ที่ไม่เรียงลำดับ = .Add / .Remove คือ O (1) แต่. รายการ (i) คือ O (n)
- เรียงลำดับ array = .Add / .Remove คือ O (n) แต่. Item (i) คือ O (log n)
พจนานุกรม
หน่วยความจำ
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
เพิ่ม
- เพิ่ม
HashArray(n) = Key.GetHash
# O (1)
- เพิ่ม
KeyArray(n) = PointerToKey
# O (1)
- เพิ่ม
ItemArray(n) = PointerToItem
# O (1)
ลบ
For i = 0 to n
ค้นหาi
โดยที่HashArray(i) = Key.GetHash
# O (log n) (อาร์เรย์ที่เรียงลำดับ)
- ลบ
HashArray(i)
# O (n) (อาร์เรย์ที่เรียงลำดับ)
- ลบ
KeyArray(i)
# O (1)
- ลบ
ItemArray(i)
# O (1)
รับไอเทม
For i = 0 to n
ค้นหาi
โดยที่HashArray(i) = Key.GetHash
# O (log n) (อาร์เรย์ที่เรียงลำดับ)
- กลับ
ItemArray(i)
วนซ้ำ
For i = 0 to n
, กลับ ItemArray(i)
เรียงลำดับ
หน่วยความจำ
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
เพิ่ม
- เพิ่ม
KeyArray(n) = PointerToKey
# O (1)
- เพิ่ม
ItemArray(n) = PointerToItem
# O (1)
For i = 0 to n
ค้นหาi
ที่KeyArray(i-1) < Key < KeyArray(i)
(โดยใช้ICompare
) # O (n)
- เพิ่ม
OrderArray(i) = n
# O (n) (อาร์เรย์ที่เรียงลำดับ)
ลบ
For i = 0 to n
หาi
ที่KeyArray(i).GetHash = Key.GetHash
# O (n)
- ลบ
KeyArray(SortArray(i))
# O (n)
- ลบ
ItemArray(SortArray(i))
# O (n)
- ลบ
OrderArray(i)
# O (n) (อาร์เรย์ที่เรียงลำดับ)
รับไอเทม
For i = 0 to n
หาi
ที่KeyArray(i).GetHash = Key.GetHash
# O (n)
- กลับ
ItemArray(i)
วนซ้ำ
For i = 0 to n
, กลับ ItemArray(OrderArray(i))
SortedList
หน่วยความจำ
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
เพิ่ม
For i = 0 to n
ค้นหาi
ที่KeyArray(i-1) < Key < KeyArray(i)
(ใช้ICompare
) # O (บันทึก n)
- เพิ่ม
KeyArray(i) = PointerToKey
# O (n)
- เพิ่ม
ItemArray(i) = PointerToItem
# O (n)
ลบ
For i = 0 to n
หาi
ที่KeyArray(i).GetHash = Key.GetHash
# O (log n)
- ลบ
KeyArray(i)
# O (n)
- ลบ
ItemArray(i)
# O (n)
รับไอเทม
For i = 0 to n
หาi
ที่KeyArray(i).GetHash = Key.GetHash
# O (log n)
- กลับ
ItemArray(i)
วนซ้ำ
For i = 0 to n
, กลับ ItemArray(i)