如何查找哈西表(50分)

  • 主题发起人 主题发起人 blacwet
  • 开始时间 开始时间
B

blacwet

Unregistered / Unconfirmed
GUEST, unregistred user!
一个简单的问题:如何查找哈西表?当哈西表的地址是动态分配时?如何定位到所需的节点呢
 
hash似乎就是散列,科班出身的都知道的,我这半路出家的还没有仔细的研究过。
Hash 表是不用查找的,有算法直接映射到实际地址,映射到哪里要看你的算法了。
你可以根据你的需要实现你的Hash 函数。别的建议你去看看数据结构或者算法的书都有介绍的,
比较简单。
 
典型的Hash表一般是一个数组,数组元素的位置就是Hash值,查找很简单,得到被查找目标的Hash值,
定位到对应的元素,该元素的值就是你要的东东了.
一个例子:
一个Hash表数组为: Hash[] ,大小为3, 其中构造Hash表的算法为 HashValue:=SomeValue mod 3
那么 SearchValue(n):=Hash[n mod 3];
就是这么简单!
 
哈希表的实现方法很多,但是都比较简单。其实找一本清华大学的《数据结构》(
一定要找pascal版的,现在清华出的还有C语言和C++版),看它1到n个小时就会掌握了。
常见的构造哈希函数的构造方法有:
直接定址法 数字分析法 平方取中法 折叠法 除留余数法 随机数法
常见的处理冲突的方法有:
开放定址法 再哈希法 链地址法 建立一个公共溢出区
在哈希表上进行查找的过程和哈希造表的过程基本相同。
最后, delphi中有Thashedstringlist可以用, 你自己慢慢看delphi的帮助吧
THashedStringList maintains a list of strings using an internal hash table.
Unit
IniFiles
Description
THashedStringList is a string list that uses a hash table internally to speed
the process of locating strings. It is used internally by TMemIniFile to
manage the strings from an INI file, but can be used in the same way as
any other string list. By using THashedStringList instead of TStringList,
you can improve performance when the list contains a large number of strings.
 
一般的书上讲的哈西表都是已经确定好分配的地址,然后根据预先定义好的映射去查找。
但是现实中,地址是动态分配的。怎么映射呢?
现在的问题是这样:因为数据量很大,并且哈西表的查找是递归的。所以对查找速度要求很高
我用一个很大的数组来实现的查找:
hash[0..65535,1..10],前面是哈西键值,后面是类似链地址的方法解决冲突,
结构是:
record
boardM:Int64;//两个64位数来解决冲突
boardC:Int64;
Value:Single;//16位的是要用到的值
end;
但是由于数据量太大,导致冲突很多,速度很慢,效率也很低。所以我想采用32位或者是64位的键值。
但是所需的空间太大:一个节点占用18个字节。32位就需要70多G的存储空间!
我看一般的书上不是用链表实现的吗?如何实现和查找?
再声明一遍:要表示一个确定的值,需要两个64位数
 
你的数据量有多大? 若采用2^16的值域,平均每个值有多少重复?如果超过32个,可以考虑采用
值域为2^20..2^24的Hash表(2^32实在太大了,内存都装不下,还怎么查?).
如果允许,建议采用多个Hash表的方法,每个Hash表采用的Hash算法都不同,这样两个16Bit
值域的Hash表的完全冲突概率可以和一个32bit的Hash表相当.
例子:
Hash1[0..65535,1..10] Hash2[0..65535,1..10]
查找时将两个Hash表的结果都取出来,然后求它们的交集(相当于从一个32Bit的Hash表中进行
查询),如果只有一个结果,就OK了,否则... 否则再增加Hash表的个数,直到不可能发生冲突为止!
(我估计最多采用4个16Bit的Hash表就不会发生冲突了)
 
多人接受答案了。
 
后退
顶部