【必须学好】字典与哈希

本文深入解析字典数据结构及其哈希表实现方式,详细讲解键值对存储、查找、冲突解决等核心操作,以及哈希函数在提高检索效率中的重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

在实际问题中,按照给定的值进行数据查询是经常遇到的,比如,在电话号码簿中查询某个人的电话号码;在图书馆中按照ISBN编号查找某本书的位置;在地图中按照坐标查找某个地点的地名等等。为此,人们创造了一种能够根据记录的关键码(也就是用以标识数据在记录中的存放位置的数据项)方便的检索到对应的记录信息的数据结构,这就是字典(Dictionary)

2.2.1字典的定义

我们都使用过字典,如英汉字典、成语字典,图书的检索目录、电话簿等也可以看作广义上的字典。在计算机科学中,把字典也当成一种数据结构。

我们把字典定义为“键-值对”(Key-Value Pair)的集合。根据不同的问题,我们为名字和值赋予不同的含义,比如,在英汉字典中,英文单词是名字,此单词的中文解释条目是值;在电话簿中,人名是名字,此人名对应的电话号码是值。

字典最基本的操作包括:find(查找)add(插入)remove(删除),分别用来从字典中检索数据、插入数据和删除数据。在实际存储中,我们将“键-值对”存储于记录中,通过键(也就是“键-值对”中的名字)来标识该“键-值对”。“键-值对”的存放位置和其键之间的对应关系用一个二元组表示:(,值的位置)

从字典中查找“键-值对”的最简单方法就是使用数组存储,然后在查找的时候遍历此数组,当遍历到和被查找的“键-值对”的名字相同项的时候,这个“键-值对”就被找到了。这种最朴实的方式肯定是不能满足实际要求的,因此人们发明了一种检索效率非常高的组织字典数据的方法,即哈希表结构。

2.2.2哈希表与哈希方法

哈希方法在“键-值对”的存储位置与它的键之间建立一个确定的对应函数关系hash(),使得每一个键与结构中的一个唯一的存储位置相对应:

存储位置=hash()

在搜索时,首先对键进行hash运算,把求得的值当做“键-值对”的存储位置,在结构中按照此位置取“键-值对”进行比较,若键相等,则表示搜索成功。在存储“键-值对”的时候,依照相同的hash函数计算存储位置,并按此位置存放,这种方法就叫做哈希方法,也叫做散列方法。在哈希方法中使用的转换函数hash被称作哈希函数(或者散列函数)。按照此中算法构造出来的表叫做哈希表(或者散列表)

哈希函数建立了从“键-值对”到哈希表地址集合的一个映射,有了哈希函数,我们就可以根据键来确定“键-值对”在哈希表中的位置的地址。使用这种方法由于不必进行多次键的比较,所以其搜索速度非常快,很多系统都使用这种方法进行数据的组织和检索。

举一个例子,有一组“键值对”:<5,tom><8,Jane><12,Bit><17,Lily><20,sunny>,我们按照如下哈希函数对键进行计算:hash(x)=x%17+3,得出如下结果:hash(5)=8hash(8)=11hash(12)=15hash(17)=3hash(20)=6。我们把<5,tom><8,Jane><12,Bit><17,Lily><20,sunny>分别放到地址为8111536的位置上。当要检索17对应的值的时候,只要首先计算17的哈希值为3,然后到地址为3的地方去取数据就可以找到17对应的数据是“Lily”了,可见检索速度是非常快的。

2.2.3冲突与冲突的解决

通常键的取值范围比哈希表地址集合大很多,因此有可能经过同一哈希函数的计算,把不同的键映射到了同一个地址上面,这就叫冲突。比如,有一组“键-值对”,其键分别为123617251330930976,采用的哈希函数是:

public static int hash(int key)

{

return key%73+13420;

}

则将会得到hash(12361)=hash(7251)=hash(3309)=hash(30976)=13444,即不同的键通过哈希函数对应到了同一个地址,我们称这种哈希计算结果相同的不同键为同义词。

如果“键-值对”在加入哈希表的时候产生了冲突,就必须找另外一个地方来存放它,冲突太多会降低数据插入和搜索的效率,因此希望能找到一个不容易产生冲突的函数,即构造一个地址分布比较均匀的哈希函数。常用的哈希函数包括:直接定址法、数字分析法、除留余数法、乘留余数法、平方取中法、折叠法等。应该根据实际工作中关键码的特点选用适当的方法。

虽然采用合适的哈希方法能够降低冲突的概率,但是冲突仍然是不可避免的,处理冲突的最常用方法就是“桶”算法:假设哈希表有m个地址,就将其改为m个“桶”,其桶号与哈希地址一一对应,每个桶都用来存放互为同义词的键,也就是如果两个不同的键用哈希函数计算得到了同一个哈希地址,就将它们放到同一个桶中,检索的时候在桶内进行顺序检索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值