added cactus theme files

This commit is contained in:
2022-07-31 17:32:45 -07:00
parent 1c054014c6
commit b32268d438
142 changed files with 17322 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
---
title: java散列知识点总结
date: 2017-02-18 19:19:01
category: notes
tags:
- Algorithms
keywords:
- hash
- 散列
- 哈希
- java
---
java 的根类 `Object` 具有 `hashcode` 方法。当 `equal` 方法被重写时也应当重写 `hashcode` 方法。
## 基本数据类型的散列码
* `byte` `short` `int` `char` 类型的搜索键将会转换为 `int`
* `float` 类型的搜索键使用 `Float.floatToIntBits(key)` 作为散列码。
* `long` 类型的搜索键会进行折叠操作,如下:
```java
iny hashCode = (int) (key ^ (key >> 32));
```
* `double` 类型的搜索键会使用 `Double.doubleToLongBits(key)` 方法转换为 `long` 类型然后再进行折叠。
## 字符串类型的散列码
对于字符串一般使用多项式散列码进行计算,
~~这里放个公式的图~~
b的较好取值为3133373941。在 java String 类中 `b` 取31。
```java
public static int hash(String key, int tableSize)
{
int hashVal = 0;
for (int i = 0; i < key.length(); i++)
hashVal = 37*hashVal + key.charAt(i);
hashVal %= tableSize;
if (hashVal < 0)
hashVal += tableSize;
return hashVal;
}
```
## 压缩散列码
由于散列码可能是很大的正数,通常应该对其进行压缩以防止超出索引的范围。若索引范围为 `0 ~ n - 1` ,通常的做法是 `h(hashCode) = hashCode % N` 选择N为大于2的素数。
`java.util.HashMap` 的实现中将N设置为2的幂值这样可以使用位运算代替上述的取模`h(hashCode) = hashCode & (N - 1)` ,两者是完全等价的。
## 处理冲突
### 开放地址法
开放地址法是在冲突发生时,在散列表中找到一个开放位置的过程。
* 线性探测,存在成簇问题
* 二次探测,存在二次成簇问题,并且不能保证一个开放的单元总是可以被找到。
* 再哈希法
### 链地址法
链地址法是将具有同样索引的条目放在同一位置,每个位置使用一个桶(ArrayList or LinkedList)来放置多个条目。
## 装填因子
装填因子衡量一个散列表有多满。`lamda = n / N` 。对于开放地址法,装填因子介于 0 ~ 1对于链地址法装填因子可能为任意值。通常开放地址法需要将装填因子维持在0.5以下而链地址法为0.9以下。`java.util.HashMap` 采用了阈值0.75。