数据结构-哈希表

引言

    假设现在有5个值,{5,2,3,2,4},如果把他们放到线形表中的话,我们要查找某个值只能按顺序去搜索,这样耗费的时间就比较多,我们希望可以减少时间的消耗,哈希表在这种情况下出现的。

    哈希表,是一种以空间换取时间的数据结构;

哈希表是怎么建立的

    我们通过对需要存储的值(value)设定一个函数(规则),计算出一个key(地址),然后把value放到key里面,就是键值对{key,value}了,然后把通过相同函数生成的键值对放到同一对象中进行管理,这个对象就是哈希表。

    Hash(value)-> key

    这样如果我们想访问某个value,就不用对表进行遍历比较,把value作为参数给Hash函数计算出一个key,就可以直接去key那里取到我们想要的数据了。

例:
Map hashMap = new HashMap();
int[] a = {52324}
// Hash函数
int Hash(value) {
	// 某种规则
	int key = value + 1;
	return key;
}

for(int i = 0; i < a.length; i ++){
	int key = Hash(a[i]);
	hashMap.put(key, value);
}

哈希冲突

    从上面的例子中我们不难发现,在value相同的时候,key也会相同,这样的话通过key查找会得到两个value,显然不是我们想要的。这样的情况称之为哈希冲突

解决哈希冲突的办法

1.开放地址方法

(1)线性探测
    按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上往后加一个单位,直至不发生哈希冲突。 
(2)再平方探测
    按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上先加1的平方个单位,若仍然存在则减1的平方个单位。随之是2的平方,3的平方等等。直至不发生哈希冲突。
(3)伪随机探测
    按顺序决定值时,如果某数据已经存在,通过随机函数随机生成一个数,在原来值的基础上加上随机数,直至不发生哈希冲突。

2.链式地址法(HashMap的哈希冲突解决方法)

    对于相同的值,使用链表进行连接。使用数组存储每一个链表。
    优点:
    (1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
    (2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
    (3)开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
    (4)在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。
    缺点:
    指针占用较大空间时,会造成空间浪费,若空间用于增大散列表规模进而提高开放地址法的效率。

3.建立公共溢出区

    建立公共溢出区存储所有哈希冲突的数据。

4.再哈希法

    对于冲突的哈希值再次进行哈希处理,直至没有哈希冲突。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值