第10章 散列和Hashtable类
散列是一种常见的存储数据的技术,采用这种技术可以非常迅速地插入和检索数据。散列所采用的数据结构被称为是散列表。尽管散列表提供了快速地插入、删除、以及检索数据的操作,但是诸如查找最大值或最小值这样的查找操作,散列表却无法执行得非常快。对于这类操作,其他数据结构会更适合。
10.1 散列概述
散列表数据结构式围绕数组设计的,虽然可以稍后根据需要增加数组的大小,但是数组是由第0号元素一直到一些预定义尺寸的元素组成的
10.2 选择散列函数
选择散列函数的依据是所用键的数据类型。如果所用的键是整数,那么最简单的函数是返回键对数组大小取模的结果。
class Chapter10
{
static void Main()
{
string[] names = new string[99];
string name;
string[] someNames = new string[] { "David", "Jennifer", "Donnie", "Mayno", "Raymod", "Bernica", "Clayton", "Beata", "Michael", "wwg" };
int hashVal;
for (int i = 0; i < 10;i++ )
{
name = someNames[i];
hashVal = SimpleHash(name, names);
names[hashVal] = name;
}
ShowDistrib(names);
}
static int SimpleHash(string s, string[] arr)
{
int tot = 0;
char[] cname;
cname = s.ToCharArray();
for (int i = 0; i < cname.GetUpperBound(0); i++)
{
tot += (int)cname[i];
}
return tot % arr.GetUpperBound(0);
}
static void ShowDistrib(string[] arr)
{
for (int i = 0; i <= arr.GetUpperBound(0); i++)
if (arr[i] != null)
Console.WriteLine(i + " " + arr[i]);
}
}
static int BetterHash(string s, string[] arr)
{
int tot = 0;
char[] cname;
cname = s.ToCharArray();
for (int i = 0; i < cname.GetUpperBound(0); i++)
{
tot += 37 * tot + (int)cname[i];
}
tot = tot % arr.GetUpperBound(0);
if (tot < 0)
tot += arr.GetUpperBound(0);
return (int)tot;
}
这个函数利用霍纳法则来计算(关于37的)多项式函数。
10.3 查找散列表中数据
为了在散列表中查找数据,需要计算键的散列值,然后访问数组中的对应元素,就是这样简单。下面是函数
Static bool InHash(string s , string[] arr)
{
Int hval = BetterHash(s,arr)
If (arr[hval]==s)
return ture;
else
return false;
}
10.4 解决冲突
在处理散列表的时候,不可避免的会遇到这种情况,即计算出的键的散列值已经存储了另外一个键,这就是所谓的冲突。
在发生冲突的时候可以使用几种技术,这些技术包括桶式散列法、开放定址法、和双重散列法。
10.5 Hashtable类
10.5.1实例化Hashtable 对象并且给其添加数据
10.5.2 从散列表中分别检索键和数值
10.5.3 检索基于键的数值
10.5.4 Hashtable类的实用方法
10.6 Hashtable的应用: 计算机术语表