C#中用哈希表搜索对象

.NET Framework中的大多数容器都是序列式容器(sequence containers):它们按顺序存储对象。这 种类型的容器功能很多——你可以以任何特殊的顺序来存储任意数量的对象。

然而,这种多功能性是以一定的性能为代价的。在一个序列中查找一个特殊的对象所需要的时间取决 于容器中对象的数量。如果我们没有对容器中元素进行排序,那么随着元素数量的增加,你所需要的查找 时间也就直线增加了:如果容器中元素的数量增加了一倍,那么你用来查找一个特殊元素的时间也就增加 了一倍。然而,如果我们对容器中的元素进行了排序,那么查找时间就是随着元素数量的对数而增加的了 :要使查找一个元素的时间增加一倍,你必须使集合中的元素数量增加四倍。如果你用一个key来搜索对 象,你可以用比序列式容器更好的方法来存储你的对象。你可以用哈希表(hash table)。

哈希表根据一个叫做hash的数字关键字(key)将对象存储在buckets中。hash value是从对象中的值 计算得来的一个数字。每个不同的hash value都会创建一个新的bucket。要查找一个对象,你只需要计算 这个对象的hash value并搜索相应的bucket就行了。通过快速地找到相应的bucket,就可以减少你需要搜 索的对象数量了。

例如,设想在一个数据结构中有一些客户记录,你想通过信用卡号来搜索那些记录。一个简单的哈希 函数将运用信用卡号的后两位数字,这会形成100个buckets——从00到99的每个两位数的数字都会创建一 个bucket。(同样,运用后三位数字会创建1000个buckets。)只需要查询一个bucket,你就可以找到任 何记录了,而不需要查询所有的buckets。

然而,同任何事情一样,并不是一切都这么简单的。如果你用信用卡号创建了一个哈希函数,而你想 通过姓名来查找客户,你就需要查询整个哈希表,这样会花很多时间。这是因为哈希表是用一个不同的字 段作为key的。而且,如果你查询整个哈希表,那么元素就没有必要按你期望的顺序来排列了。元素是根 据hash value来排列的,而不是根据keys排列的。

在本篇文章中,我将详述我在前面的文章(“为更好的集合创建类”)中的样例,让你修改一条员工 记录。假设有一个很大的公司,公司里有上千位员工,你想用最快的方法来找到一条记录。所有员工的一 个哈希表可以使搜索在最短的时间完成。

一个哈希函数需要有一定的属性。对于初学者来说,哈希函数必须是不变的。这就是说相同的key必须 生成相同的hash value,一旦创建了对象,hash value就不能改变了。如果hash value改变了,你在哈希 表中就再也找不到相应的对象了。

哈希函数需要的第二个属性就是能够平均分配buckets。如果所有的对象都生成相同的hash value,那 么就需要更多的时间来查找一个特殊的对象。

实际上,这两个原则是很容易遵循的。在.NET Framework中有178个类重载了GetHashCode(),从而更 好地发挥它们的作用。所有的.NET FCL(Framework Class Library)中类的实现都确保了hash value的 更好的分配,并遵循了唯一性的原则。你应该确定你自己的类和结构是否需要重载GetHashCode()方法。 最简单的(通常也是最好的)方法就是在key中选取一个不变的成员,并运用那个成员所生成的hash value。

员工数据库的一个明显的hash key就是社会保险号(Social Security Number)。它不仅不会改变, 而且九位数的这个号码也可以让你任意运用以得到你期望的性能。你可以下载样例,看看运用hash keys 进行搜索和运用序列式容器进行搜索有什么不同。

要把员工添加到一个哈希表中,你可以创建一个九位数的号码并把它作为key:

int hash = 111223333;
for (int i = 0; i < 100; i++)
{
   string lastname = "Person" + i.ToString();
   e = new Employee ("Employee", lastname, (200-i)*200);
   members.Add(hash++, e);
}

时间: 2025-01-02 00:42:53

C#中用哈希表搜索对象的相关文章

Programming Ruby——数组,哈希表和控制结构

数组和哈希表 Ruby的数组和哈希表是索引集合.两都都是保存对象集合并能通过键来读取.数组的键是数字,但是 哈希表则支持对象作为键.它们都是随着新元素的加入要增长.在访问元素方面,数组效率比较高,但哈 希表更加的灵活.无论是数组还是哈希表,都能保存不同类型的对象:你可以使用一个数组保存数字,字 符串和浮点数,就像你等会将会看到的那样. 你可以使用数组文本来创建和初始化一个新的数组--一个由中括号包围的元素集合.对于一个数组 ,你能通过使用中括号间的数字来获取每个元素,就如例子所演示的那样.要注意

(教学思路 C#集合二)哈希表

这一节我们来学习第二种集合,因为它的特性,可以提供一种相当有效率的搜索方法,所以在实际项目中非常实用,它就是哈希表.哈希继 承了IDictionary接口,IDictionary接口提供了key(键)/value(值)集合设计模式,这种类集合中的每个一个对象都包含一个与它相对应的 key,可以通过所指定的key找到集合中所对应的对象(value值),这个接口最重要之处在于定义了公共属性Item.values.keys,其中Item根 据指定的key返回集合中所对应的值,values用来返回集合中

JavaScript中实现键值对应的字典与哈希表结构的示例_javascript技巧

字典(Dictionary)的javascript实现编程思路: 使用了裸对象datastore来进行元素存储: 实现了两种得到字典长度的方法,一种为变量跟踪,一种为实时计算. 代码: function(){ "use strict"; function Dictionary(){ this._size = 0; this.datastore = Object.create(null); } Dictionary.prototype.isEmpty = function(){ retu

java中哈希表及其应用详解_java

哈希表也称为散列表,是用来存储群体对象的集合类结构. 什么是哈希表 数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系.当要查找一个对象时,只能以某种顺序(如顺序查找或二分查找)与各个元素进行比较,当数组或向量中的元素数量很多时,查找的效率会明显的降低. 一种有效的存储方式,是不与其他元素进行比较,一次存取便能得到所需要的记录.这就需要在对象的存储位置和对象的关键属性(设为 k)之间建立一个特定的对应关系(设为 f),使每个对象与一个唯一的存储位置

纸上谈兵: 哈希表 (hash table)

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   HASH 哈希表(hash table)是从一个集合A到另一个集合B的映射(mapping).映射是一种对应关系,而且集合A的某个元素只能对应集合B中的一个元素.但反过来,集合B中的一个元素可能对应多个集合A中的元素.如果B中的元素只能对应A中的一个元素,这样的映射被称为一一映射.这样的对应关系在现实生活中很常见,比如: A  -> B 人 -> 身份证号 日期 ->

PHP关联数组与哈希表(hash table) 不指定

PHP中有一种数据类型非常重要,它就是关联数组,又称为哈希表(hash table),是一种非常好用的数据结构. 在程序中,我们可能会遇到需要消重的问题,举一个最简单的模型: 有一份用户名列表,存储了 10000 个用户名,没有重复项: 还有一份黑名单列表,存储了 2000 个用户名,格式与用户名列表相同: 现在需要从用户名列表中删除处在黑名单里的用户名,要求用尽量快的时间处理. 这个问题是一个小规模的处理量,如果实际一点,2 个表都可能很大,比如有 2 亿条记录. 我最开始想到的方法,就是做一

浅谈算法和数据结构 十一 哈希表

在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是他们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的时间复杂度. 那么有没有查找效率更高的数据结构呢,答案就是本文接下来要介绍了散列表,也叫哈希表(Hash Table) 什么是哈希表 哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 哈希的思路很简单

AS2.0中实现数据结构-哈希表

数据|数据结构 在游戏制作中我们经常需要存储一些离散的对象数据,比如道具箱里的道具,经常需要执行插入和删除操作,而且道具之间没有联系是无序排列的.有些人会说直接用数组不就得了,但是有大量数据存储时的数组的删除插入操作的效率是很低的.因此我们需要哈希表这样的可以提供快速的插入和删除,查找操作的数据结构,不论哈希表中有多少数据,插入和删除操作只需要接近常量的时间:即O(1)的时间级.既然这么好那么我们的AS可以实现吗?当然可以!AS发展到AS2.0,已经成为在语法上更接近于Java + Pascal

php如何在数组和哈希表上工作

在数组和哈希表上工作 在C语言中, 有两种不同的基础方法用来在一个结构体中存储任意数量的独立数据元素. 两种方法都有赞成者和反对者. 向量 Vs. 链表 应用的编写通常基于特定类型数据的特性的选择, 需要存储多少数据, 以及需要多快速度的检索. 为了能够有对等的认知, 我们先来看看简单的看看这些存储机制. 向量 向量是一块连续的内存空间, 它们包含的数据有规律的间隔. 向量最常见的例子就是字符串变量(char *或char []), 它包含了一个接着一个的字符(字节)序列. char foo[4