.NET集合浅析

这个学期看了不少STL的东西,也补充了一些以前没有学过的数据结构知识。回过头来看之前写过的一些Unity脚本,发现在当时在基本只会用向量这一种数据结构的情况下,写出了许多啼笑皆非的代码。比如,当时基本只会什么都用List<>,居然在使用for循环遍历一个List的同时,尝试去删除其中的元素...因此,这里我们打开MSDN,总结一下C#中的集合与数据结构。由于受STL的影响,这里在总结归纳时,免不了与STL中的容器进行了对比。

总的来说,.NET集合分为泛型集合和非泛型集合,前者指的是集合名称后面带<T>的,而后者指ArrayList、Hashtable这种没有类型参数的集合。MSDN指出,使用泛型集合往往具备更好的性能。与STL容器相比,.NET集合的种类稍多、功能也更多,体系组织与完全不同,甚至显得比较杂乱(不过我觉得这大部分是MSDN的锅)。这里整理一下常用的集合,不仿先按照STL容器及实现方式进行分类对应:

(一)顺序容器

1. 向量:List<T> (非泛型集合:ArrayList)

.NET命名和STL体系完全不同,比如这个List就迷惑了我好久,众所周知list是STL中双向链表的名称,到了.NET却变成了向量…之前在无脑写Unity代码时,居然在使用for循环遍历一个List的同时去删除其中的元素…

2. 链表:LinkedList<T>(双向链表)

相比STL中的list统一使用迭代器,.NET的LinkedList<T>还支持一个基于节点的访问方式,使用LinkedListNode<T>类型创建节点的引用,可以通过Next、Previous属性移动指针。这种方法很像用C语言写的原始链表。

3. 队列:Queue<T>

4. 栈:Stack<T>

(二)关联容器

上面是基本的顺序容器,.NET容器的功能和STL是类似的。但到了下面的关联容器,.NET显得有些混乱了,它并没有STL关联容器“三个维度”(集合/字典、是否允许重复元素、是否有序)那样清晰的体系。这里试图找到对应于STL的容器。

5. 散列表:HashSet<T> (集合) Dictionary<TKey,TValue> (字典)

二者基本上对应于STL的unordered_set/unordered_map,即不允许重复元素,内部实现实现基于散列表。另外.NET还有个Hashtable,这个容器MSDN给出的定义是“桶”的集合,加入到其中的key(Hashtable也是字典)必须实现GetHashCode方法和Object.Equals方法。GetHashCode方法用于计算Key的散列码,返回一个整数。

6. 二叉搜索树:SortedSet<T> (集合) SortedList<TKey,TValue> (字典)

基本对应于STL的set/map,内部元素是有序的,仍然不允许元素重复。

7. 奇葩:SortedDictionary<TKey,TValue> (向量字典?)

这是一种STL中没有的集合类型。这个类型即允许循关键码访问,也允许循秩访问。MSDN指出:该集合内部维护了两个列表,分别存储key和value。猜测内部实现应该是value列表按照正常的二叉搜索树实现,是已排序的,这样通过key可以找到对应value,和普通的map无异;而key列表是凭空多出来的,猜测它是一个数组,这样我们可以通过“秩”(即索引)来找到对应的key,再通过这个key按照上述步骤找到value。

到现在为止,我们还没有找到对应于STL关联容器中multi_前缀的集合类型,即允许重复元素的循关键码访问集合。在介绍HashSet<T>时,MSDN给出了下面一段话:“A HashSet<T> collection is not sorted andcannot contain duplicate elements. If order or element duplication is moreimportant than performance for your application, consider using the List<T> class together with the Sort method.”微软的意思似乎是.NET并不提供类似的集合,而是建议通过对List<T>进行排序实现。所以应该怎么做呢?

 

参考文献

1. MSDN:https://docs.microsoft.com/zh-cn/dotnet/standard/collections/

2. 《C++ Primer》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值