hashtable的解释

哪个高手给你说“哈西表就是键(key)与值(value)的对应。”的?要么就是他不耐烦随便搪塞你的,要么就是他不是高手没有理解真正的含义。  
  “哈西表就是键(key)与值(value)的对应。”这句话实际上说的Dictionary——字典。当然哈希表本身也是一个字典,也就是说他是一个通过“键”查询“内容”的集合对象,只是他提供了一种字典本身没有规定的特性——高速。下面是关于HashTable的平均时间复杂度表(和其他数据结构比较,均不包括内存分配):  
   
                            哈希表                     链表                     数组                         排序数组  
  添加                   O(c)                         O(1)                     O(1)                         O(log2(n))                          
  查询                   O(c)                         O(n/2)                 O(n/2)                     O(log2(n))  
  删除                   O(c)                         O(1)                     O(1)                         O(n/2)  
   
  c是一个常数级别的东西,和n关系不是非常大,基本上相当于1~15之间,一般你可以认为是2或者3。这里面的数据不是很精准,大概意思意思。你可以看出来,哈希标有着各项性能均比较出色的表现,没有哪一向是排在最后面的,甚至和最快的都不会相差多少。但是随便哪一种数据结构都会至少有某一项是远远落后于哈希表的,所以在编译器里面就是用哈希表储存你定义的表识符的。  
  从上表也可以看出,哈希表最出色的地方在于查询。也就是说如果你需要在大量数据当中反反复复进行大量的(排序无关的)查询的话,用哈希表就最适合不过了。如果不是这种情况,用哈希表也不会表现太差。但是哈希表也有他的缺点:  
   
  1、他是一个字典,也就是说他需要你的数据中能有一个唯一的“键”来表识你的数据。比如说如果你的数据是某个人的姓名以及他的一些其他情况,那么一旦有同名的那就会出问题了——会被认为是同一个人,甚至你根本就没有办法把另外一个人添加进去。因此,没有或者不能保证有唯一键值的数据不能够用哈希表。实际上哈希表还需要这个“键”能够产生哈希值,只是在.NET里面任何东西都有哈希值(Object.Hashcode),所以你就不用担心这个问题了。  
   
  2、他是一个字典,也就是说他除了需要保存你的数据之外,还要保存你的“键”,或者还有一些且他的原因,使得它的空间额外开销是O(xN)级别的,也就是说会相对消耗更多的空间。如果数据量非常大的话,用哈希也会更容易受到限制。其他一些例如联表、树等在这方面要表现得好的多,他们最多也就需要O(4N)或者稍微多一点,哈希表的那个x要比这个大一些。表现得最好的是数组类的数据结构,根本就是0(这里讨论的是额外的)。实际上传统的哈希表是一次分配固定大小的空间,并且不会再变化的,因此很多时候会有很多空间是没有被利有到的,也就是说他的利用率比较低(这样有助于减小前面的c值),所以占用空间会非常大。不过.NET里面的哈希表默认的装载因子是1,也就是全满的,所以相对较好。当然,一般来说这些额外的空间都不会异常的大,一般都是可以接受的。这一点说明哈希表对于数据量太大或者对空间有严格要求的地方是不适合的,虽然你还是可以选择他。  
   
  3、哈希表之所以快,是因为它的每个元素在哈希表里面的存储位置是通过你的键的哈希值计算得到的,因此存储的顺序是随机的并且是不能够控制的。因此如果你需要排序,或者需要有排序相关的查询功能,例如找出身高为160到175之间的所有人,那么哈西表的表现就会非常差,尤其是这些值并不是键值的时候。这个时候排序数组,B树等能够提供比他优秀得多的性能。如果你的数据需要排序,或者排序相关的功能,那么就请你忘了哈希吧,它本身不但没有这个功能,甚至是和这个功能想冲突的。当然,你可以通过其他数据结构提供排序能力,但是这样会增加更多的额外空间开销,编码也会相对复杂不少。  
   
  简单点说,哈希表是:一个集合,一个字典,一个空间换时间的方法,一个随机乱序存储的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值