散列(hashtable)

散列作为常用 的数据结构,之前上课的时候书上没有太多的篇章有讲,因此专门复习一下

1、空间换时间

先看一个简单的问题:给出N个正整数,再给出M个正整数,求问这M个整数的每一个是否有在N中出现,其中N,M<10^5;

对于这类问题,最直观的就是对于每个M,遍历N,但是复杂度达到了O(N*M),显然复杂度过大

那么给出的解决方案就是以空间换取时间,即设定一个bool型数组boolTable[100010],其为真,表示N有x这个值;说明,boolTable需要提前初始化为false ,显然这样的复杂度为O(N+M),先通过N对boolTable更新值,再判断M是否出现,同样假如想判断出现多少次,只需要将bool数组更改为Int类型即可。

上面问题是直接将值作为数组的下标来对这个数的性质j进行统计。这是一个非常实用的空间换取时间的策略。

·

2、散列函数

但是对于大整数或者字符串来说,怎么将乱七八糟的元素转化成一个能够接受的范围?

那就是散列--【将元素通过一个函数转化为整数,使得该整数可以唯一的表示这个元素】,这个函数就是散列函数

在数据结构课程上,我学的是哈希函数,差不多咧

2.1 除留余数法

h(K)=K mod m  

m是哈希表的长度,m最好是1.1n--1.5n的素数,n是存储数的个数,而不是数的范围

 

2.2 直接定址法

h(K)=K+C

2.3 数字分析法

 

3、冲突解决

对于不同的数key1、key2,有h(key1)==h(key2),那么我们说发生了冲突

3.1线性探测法

如果发生冲突,就找下一个位置+1

3.2 平方探测法

H(key)+1,H(key)-1,H(key)+4,H(key)-4,H(key)+9

3.3 链地址法

把所有h(key)相同的key用一个单链表连接,

 

4、字符串hash

上面都是学过的东西,对于key不是整数如何设计散列函数呢?

一个例子是二维坐标,假设一个P点(x,y),其中0<x,y<range,那么令H(p)=x*range+y

 

对于字符串来说,给出的解决方案是先将字符串转化为26/52(大小写)/62(加数字)进制,再转化为十进制作为散列值

 

 

 

 

 

 

 

 

### 回答1: HashMap和Hashtable都是Java中用于存储键值对的数据结构,但是它们有一些显著的不同点: 1. 线程安全:Hashtable是线程安全的,而HashMap是线程不安全的。 2. 允许空键和空值:HashMap允许空键和空值,而Hashtable不允许空键和空值。 3. 性能:因为HashMap是线程不安全的,所以在单线程环境中它的性能比Hashtable好。 4. 方法:HashMap的put()和remove()方法在操作失败时会返回null,而Hashtable的put()和remove()方法会抛出异常。 5. 使用场景:因为HashMap是线程不安全的,所以它更适合在单线程环境中使用,而Hashtable则更适合在多线程环境中使用。 ### 回答2: HashMap和Hashtable是Java中的两种常用的集合类,它们都实现了Map接口,用于存储键值对。 首先,HashMap和Hashtable的主要区别在于线程安全性。Hashtable是线程安全的,而HashMap不是。因为Hashtable的所有方法都是同步的,可以在多线程环境下使用,但是这也导致了效率较低。而HashMap则不提供同步,如果在多线程环境下使用需要自己进行同步处理。 其次,HashMap允许将null作为键和值,而Hashtable不允许。这是因为Hashtable使用了Enumeration迭代器,而null值会导致NullPointerException。 另外,HashMap是非线程安全的,但是在大多数情况下比Hashtable效率更高,因为Hashtable需要额外的同步操作。在单线程环境下,推荐使用HashMap,而在多线程环境下需要线程安全的情况下可以使用Hashtable或者ConcurrentHashMap。 此外,HashMap的键对象可以是非线程安全的,但是Hashtable的键对象必须是线程安全的。这是因为Hashtable在计算键的散列值时,会直接使用键对象的hashCode方法,而HashMap则会使用键对象的hashCode方法计算散列值,再通过散列值计算得到数组的下标位置。 综上所述,HashMap和Hashtable的区别主要体现在线程安全性和对null值的处理上。在单线程环境下选择HashMap,在多线程环境下选择线程安全的Hashtable或者ConcurrentHashMap。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值