字典
前言:字典是一种非常复杂的数据结构。这种数据结构允许按照某个键来访问元素。字段也称为映射或者散列表。字典的主要的特征是能根据键快速查找值。有可以自由的添加和删除元素。这有像List<T>类。但是没有在内存中移动后续元素的性能开销。
下图是字典的一个简化表示。其中的employee-id(如B4711)是添加到字典中的键。键会转换为一个散列。利用散列创建一个数字。它将索引与值关联起来。然后 索引包含一个到值的链接。该图是做了简化的处理。因为一个索引可以关联多个值。索引可以存储为一个树形结构。
.Net Framwork提供了几个字典类,可以使用的最主要的类是Dictionary<TKey,TValue>。
一.键的类型
用作字典中的键的类型必须重写Object类的GetHashCode()方法。只要字典类需要确定元素的位置,就可以调用GetHashCode()方法。GetHashCode()方法返回的int由字典用于计算在对应位置放置元素的索引。这里不介绍这个算法。我们只需要知道,它涉及素数,所以字典的容量是一个素数。GetHashCode()方法实现必须满足如下的要求:
1.1:相同的对象总是返回相同的值。
1.2:不同的对象可以返回相同的值。
1.3:它应执行的比较快,计算的开销不大。
1.4:它不能抛出异常。
1.5:它应至少使用一个实例字段。
1.6:散列代码值应平均分布在int可以存储的整个数字范围上。
1.7:散列代码最好在对象的生存期中不发生变化。
二:字典的示例
static void Main(string[] args) { Dictionary<int, string> dic = new Dictionary<int, string>(); dic.Add(1, "张三"); dic.Add(2, "李四"); dic.Add(3, "王五"); //新值替代旧值 dic[1] = "新来的"; foreach (KeyValuePair<int,string> kv in dic) { Console.WriteLine("{0}---{1}",kv.Key,kv.Value); } Console.ReadKey(); }
三:有序字典
SortedDictionary<TKey,TValue>类是一个二叉搜索树。其中的元素根据键来排序。该键类型必须实现IComparable<TKey>接口。如果键的类型不能排序,则还可以创建一个实现了IComparer<TKey>接口的比较器。将比较器用作于有序字典的构造函数的一个参数。
SortDictionary<TKey,TValue>类和SortedList<TKey,TValue>类的功能类似。但是因为SortedList<TKey,TValue>实现为一个基于数组的列表。而SortDictionary<TKey,TValue>类实现为一个字典,所有他们有不同的特征。
3.1:SortedList<TKey,TValue>类使用的内存比SortDictionary<TKey,TValue>类少。
3.2:SortDictionary<TKey,TValue>类的元素插入和删除操作比较快。
3.3:在用已经排序好的数据填充集合时,如不需要修改容量。SortedList<TKey,TValue>类就比较快。
注意:SortedList<TKey,TValue> 类使用的内存比SortDictionary<TKey,TValue>类少。但是SortDictionary<TKey,TValue>类在插入和删除未排序的数据时比较快。
四:性能
许多集合类都提供了相同的功能。例如:SortedList和SortedDictionary类的功能几乎完全相同的功能。但是,其性能上往往上有很大的区别。
如下图表示:
总结:数组的大小是固定的。但是可以使用列表作为动态增长集合。队列一先进先出的方式访问元素。栈以先进后出的方式访问元素。链表可以快速的插入和删除元素,但是搜索比较慢,通过键和值可以使用字典。它的搜索和插入操作比较快,集(Hashset<T>)是用于无序的唯一项。