.NET data structures: ArrayList, List, HashTable, Dictionary, SortedList, SortedDictionary — Speed, memory, and when to use each?
.NET有许多复杂的数据结构。不幸的是,它们中的一些非常相似,我不总是确定什么时候使用一个,什么时候使用另一个。我的大多数C和VisualBasic书籍都在一定程度上讨论过它们,但它们从未真正深入到任何实际细节中。
array、array list、list、hashtable、dictionary、sortedlist和sorteddictionary有什么区别?
哪些是可枚举的(ilist——可以执行"foreach"循环)?哪些使用键/值对(IDICT)?
内存占用怎么办?插入速度?检索速度?
还有其他值得一提的数据结构吗?
我仍在寻找关于内存使用和速度(big-o符号)的更多细节。
从我的头顶上:
Array 表示一个老式的内存数组,类似于普通type[] 数组的别名。可以枚举。不能自动增长。我假设插入和检索速度非常快。ArrayList —自动增长阵列。增加了更多的开销。可以枚举.,可能比普通数组慢,但仍然很快。这些在.NET中经常使用List ——我的一个fav——可以与泛型一起使用,所以您可以有一个强类型数组,例如List 。除此之外,它的行为与ArrayList 非常相似。Hashtable —普通的旧哈希表。o(1)至o(n)最坏情况。可以枚举值和键属性,并执行键/值对Dictionary —与上面相同,仅通过泛型强类型,如Dictionary 。SortedList —已排序的通用列表。在插入时放慢速度,因为它必须找出放置东西的位置。可以枚举,可能在检索时相同,因为它不必诉诸于此,但删除将比普通的旧列表慢。
我经常使用
还有很多其他的数据结构-有
如果可能的话,使用仿制药。这包括:
- 列表而不是数组列表
- 字典而不是哈希表
首先,.NET中的所有集合实现IEnumerable。
其次,许多集合是重复的,因为在框架的2.0版本中添加了泛型。
因此,尽管通用集合可能会添加特性,但在大多数情况下:
- list是arraylist的通用实现。
- 字典是哈希表的通用实现
数组是一个固定大小的集合,可以更改存储在给定索引中的值。
SortedDictionary是基于键排序的IDictionary。SortedList是基于所需IComparer排序的IDictionary。
因此,IDictionary实现(那些支持键值对的实现)是:*哈希表*词典*排序列表*排序限制
在.NET 3.5中添加的另一个集合是哈希集。它是一个支持集合操作的集合。
另外,LinkedList是一个标准的链表实现(链表是一个用于更快检索的数组列表)。
一个很好的备忘表,提到了数据结构、算法等的复杂性。
以下是一些一般性的提示:
您可以在实现
IEnumerable 的类型上使用foreach 。IList 本质上是一个IEnumberable ,具有Count 和Item 属性(使用零基索引访问项目)。另一方面,IDictionary 意味着您可以通过任何哈希索引访问项目。Array 、ArrayList 和List 都执行IList 。Dictionary 、SortedDictionary 和Hashtable 实施IDictionary 。如果您使用的是.NET 2.0或更高版本,建议您使用上述类型的通用副本。
对于这些类型上各种操作的时间和空间复杂性,您应该参考它们的文档。
.NET数据结构位于
System.Collections 命名空间中。有些类型库(如PowerCollections)提供附加的数据结构。要彻底了解数据结构,请参考CLR等资源。
.NET数据结构:更多关于为什么ArrayList和List实际上不同的讨论数组
正如一个用户所说,数组是"老派"集合(是的,数组被视为集合,但不是
首先,Microsoft.NET中的数组是"允许将多个[逻辑相关的]项视为单个集合的机制"(请参阅链接文章)。那是什么意思?数组按顺序存储单个成员(元素),一个接一个地存储在具有起始地址的内存中。通过使用数组,我们可以轻松地访问从该地址开始的顺序存储元素。好的。
除此之外,与编程101常见概念相反,数组实际上可能非常复杂:好的。
数组可以是一维的、多维的,也可以是Jadded(锯齿状的数组值得一读)。数组本身不是动态的:一旦初始化,n大小的数组就保留足够的空间来容纳n个对象。数组中的元素数不能增长或收缩。
根据本文,公共语言规范(CLS)要求所有数组都是基于零的。.NET中的数组支持非基于零的数组;但是,这并不常见。由于零基数组的"通用性",微软花费了大量时间优化它们的性能;因此,单维零基(szs)数组是"特殊"的,实际上是数组的最佳实现(而不是多维的等),因为szs对manipula有特定的中间语言指令。给他们打电话。好的。
数组总是通过引用(作为内存地址)传递的,这是需要知道的数组难题中的一个重要部分。当它们执行边界检查(将引发错误)时,也可以在数组上禁用边界检查。好的。
同样,对数组最大的阻碍是它们不可重定大小。它们具有"固定"容量。将ArrayList和List(of T)引入我们的历史:好的。arraylist-非泛型列表
arraylist(连同
在我看来,数组列表不能交错:"使用多维数组作为元素…不支持""。再一次,又一颗钉子钉进了阵列列表的棺材。arraylist也不是"类型化的"—也就是说,在所有内容的下面,arraylist只是一个对象的动态数组:
未经证实的想法:我想我记得我读过或听过我的一位教授说过,数组列表是试图从数组转移到列表类型集合的一种混蛋概念子,也就是说,虽然数组曾经是一个很大的改进,但随着进一步的发展,它们不再是最佳选择。关于托收好的。(T的)列表:arraylist变成了什么(并且希望变成什么)
内存使用的差异非常显著,以至于一个列表(Int32)消耗的内存比一个包含相同基元类型的数组列表少56%(在上面的绅士链接演示中为8 MB对19 MB:同样,链接在这里),尽管这是64位机器的复合结果。这种差异实际上证明了两件事:第一(1),装箱的int32类型"object"(arraylist)比纯的int32基元类型(list)大得多;第二(2),由于64位机器的内部工作,这种差异是指数级的。好的。
那么,有什么区别,什么是t的列表?msdn将
msdn指定此差异仅在存储基元类型而不是引用类型时起作用。同样,这种差异也在很大程度上发生:超过500个元素。更有趣的是,msdn文档中写道:"使用list(of t)类的特定类型实现而不是使用arraylist类是对您有利的……"好的。
本质上,t的list是arraylist,但更好。它是arraylist的"一般等价物"。像arraylist一样,在排序之前不能保证它是被排序的(如图所示)。list(of t)还有一些附加功能。好的。好啊。
我对这个问题表示同情-我也发现了。这个选择令人困惑,所以我科学地着手研究哪种数据结构最快(我用vb进行了测试,但我认为c是相同的,因为两种语言在clr级别都做相同的事情)。您可以在这里看到我进行的一些基准测试结果(还讨论了在哪些情况下最适合使用哪种数据类型)。
泛型集合将比它们的非泛型集合执行得更好,尤其是在迭代许多项时。这是因为拳击和拆箱不再发生。
哈希表/字典是O(1)性能,这意味着性能不是大小的函数。这很重要。
编辑:实际上,哈希表/字典<>查找的平均时间复杂度是O(1)。
它们的拼写很清楚。只需键入System.Collections。或者system.collections.generics(首选),您将得到可用内容的列表和简短描述。
高频系统交易工程哈希表与字典的重要说明:线程安全问题
哈希表是线程安全的,可供多个线程使用。字典公共静态成员是线程安全的,但不保证任何实例成员是线程安全的。
因此在这方面,hashtable仍然是"标准"选项。
最流行的C数据结构和集合
- 数组
- 阵列列表
- 表
- 链表
- 词典
- 哈希集
- 栈
- 排队
- 有序列表
C.NET有很多不同的数据结构,例如,最常见的是数组。然而,C有许多更基本的数据结构。选择要使用的正确数据结构是编写结构良好且高效的程序的一部分。
在本文中,我将介绍内置的C数据结构,包括C.NET 3.5中引入的新结构。注意,这些数据结构中的许多适用于其他编程语言。
数组
可能最简单和最常见的数据结构是数组。C数组基本上是一个对象列表。它的定义特征是所有对象都是相同的类型(在大多数情况下),并且有特定数量的对象。数组的性质允许根据元素在列表中的位置(也称为索引)快速访问元素。C数组的定义如下:
1 |
一些例子:
1 2 |
号
从上面的示例中可以看到,可以不使用元素或从一组现有值初始化数组。在数组中插入值只要合适就很简单。当元素多于数组的大小时,操作会变得昂贵,此时需要扩展数组。这需要更长的时间,因为必须将所有现有元素复制到新的更大的数组中。
阵列列表
C数据结构arraylist是一个动态数组。这意味着数组列表可以有任意数量的对象和任何类型的对象。此数据结构旨在简化向数组中添加新元素的过程。在引擎盖下,arraylist是一个数组,它的大小在每次耗尽空间时都翻倍。将内部数组的大小翻一番是一种非常有效的策略,从长远来看可以减少元素复制的数量。我们不能在这里证明这一点。数据结构非常易于使用:
1 2 3 4 |
arraylist数据结构的缺点是必须将检索到的值强制转换回其原始类型:
1 | int arrayListValue = (int)myArrayList[0] |
。
您可以在此处找到的来源和更多信息:
- C数据结构
- 收集和数据结构
- 列表与IEnumerable、IQueryable、ICollection和IDictionary
- System.Collections.Generic命名空间
- System.Collections命名空间
一般集合和非一般集合之间存在细微的差别,而不是细微的差别。它们只使用不同的底层数据结构。例如,hashtable保证一个编写器和多个读卡器不同步。字典没有。
实际上,我认为msdn有助于为所有这些问题提供很好的答案。只需查找.NET集合。