Sort the coding languages by applications. (#721)

This commit is contained in:
Yudong Jin
2023-09-04 03:19:08 +08:00
committed by GitHub
parent 8d5e84f70a
commit 9c3b7b6422
55 changed files with 6826 additions and 6826 deletions
+125 -125
View File
@@ -45,16 +45,16 @@ index = hash(key) % capacity
- **异或哈希**:将输入数据的每个元素通过异或操作累积到一个哈希值中。
- **旋转哈希**:将每个字符的 ASCII 码累积到一个哈希值中,每次累积之前都会对哈希值进行旋转操作。
=== "Java"
=== "Python"
```java title="simple_hash.java"
[class]{simple_hash}-[func]{addHash}
```python title="simple_hash.py"
[class]{}-[func]{add_hash}
[class]{simple_hash}-[func]{mulHash}
[class]{}-[func]{mul_hash}
[class]{simple_hash}-[func]{xorHash}
[class]{}-[func]{xor_hash}
[class]{simple_hash}-[func]{rotHash}
[class]{}-[func]{rot_hash}
```
=== "C++"
@@ -69,16 +69,28 @@ index = hash(key) % capacity
[class]{}-[func]{rotHash}
```
=== "Python"
=== "Java"
```python title="simple_hash.py"
[class]{}-[func]{add_hash}
```java title="simple_hash.java"
[class]{simple_hash}-[func]{addHash}
[class]{}-[func]{mul_hash}
[class]{simple_hash}-[func]{mulHash}
[class]{}-[func]{xor_hash}
[class]{simple_hash}-[func]{xorHash}
[class]{}-[func]{rot_hash}
[class]{simple_hash}-[func]{rotHash}
```
=== "C#"
```csharp title="simple_hash.cs"
[class]{simple_hash}-[func]{addHash}
[class]{simple_hash}-[func]{mulHash}
[class]{simple_hash}-[func]{xorHash}
[class]{simple_hash}-[func]{rotHash}
```
=== "Go"
@@ -93,6 +105,18 @@ index = hash(key) % capacity
[class]{}-[func]{rotHash}
```
=== "Swift"
```swift title="simple_hash.swift"
[class]{}-[func]{addHash}
[class]{}-[func]{mulHash}
[class]{}-[func]{xorHash}
[class]{}-[func]{rotHash}
```
=== "JS"
```javascript title="simple_hash.js"
@@ -117,54 +141,6 @@ index = hash(key) % capacity
[class]{}-[func]{rotHash}
```
=== "C"
```c title="simple_hash.c"
[class]{}-[func]{addHash}
[class]{}-[func]{mulHash}
[class]{}-[func]{xorHash}
[class]{}-[func]{rotHash}
```
=== "C#"
```csharp title="simple_hash.cs"
[class]{simple_hash}-[func]{addHash}
[class]{simple_hash}-[func]{mulHash}
[class]{simple_hash}-[func]{xorHash}
[class]{simple_hash}-[func]{rotHash}
```
=== "Swift"
```swift title="simple_hash.swift"
[class]{}-[func]{addHash}
[class]{}-[func]{mulHash}
[class]{}-[func]{xorHash}
[class]{}-[func]{rotHash}
```
=== "Zig"
```zig title="simple_hash.zig"
[class]{}-[func]{addHash}
[class]{}-[func]{mulHash}
[class]{}-[func]{xorHash}
[class]{}-[func]{rotHash}
```
=== "Dart"
```dart title="simple_hash.dart"
@@ -189,6 +165,30 @@ index = hash(key) % capacity
[class]{}-[func]{rot_hash}
```
=== "C"
```c title="simple_hash.c"
[class]{}-[func]{addHash}
[class]{}-[func]{mulHash}
[class]{}-[func]{xorHash}
[class]{}-[func]{rotHash}
```
=== "Zig"
```zig title="simple_hash.zig"
[class]{}-[func]{addHash}
[class]{}-[func]{mulHash}
[class]{}-[func]{xorHash}
[class]{}-[func]{rotHash}
```
观察发现,每种哈希算法的最后一步都是对大质数 $1000000007$ 取模,以确保哈希值在合适的范围内。值得思考的是,为什么要强调对质数取模,或者说对合数取模的弊端是什么?这是一个有趣的问题。
先抛出结论:**当我们使用大质数作为模数时,可以最大化地保证哈希值的均匀分布**。因为质数不会与其他数字存在公约数,可以减少因取模操作而产生的周期性模式,从而避免哈希冲突。
@@ -252,57 +252,6 @@ $$
请注意,不同编程语言的内置哈希值计算函数的定义和方法不同。
=== "Java"
```java title="built_in_hash.java"
int num = 3;
int hashNum = Integer.hashCode(num);
// 整数 3 的哈希值为 3
boolean bol = true;
int hashBol = Boolean.hashCode(bol);
// 布尔量 true 的哈希值为 1231
double dec = 3.14159;
int hashDec = Double.hashCode(dec);
// 小数 3.14159 的哈希值为 -1340954729
String str = "Hello 算法";
int hashStr = str.hashCode();
// 字符串 Hello 算法 的哈希值为 -727081396
Object[] arr = { 12836, "小哈" };
int hashTup = Arrays.hashCode(arr);
// 数组 [12836, 小哈] 的哈希值为 1151158
ListNode obj = new ListNode(0);
int hashObj = obj.hashCode();
// 节点对象 utils.ListNode@7dc5e7b4 的哈希值为 2110121908
```
=== "C++"
```cpp title="built_in_hash.cpp"
int num = 3;
size_t hashNum = hash<int>()(num);
// 整数 3 的哈希值为 3
bool bol = true;
size_t hashBol = hash<bool>()(bol);
// 布尔量 1 的哈希值为 1
double dec = 3.14159;
size_t hashDec = hash<double>()(dec);
// 小数 3.14159 的哈希值为 4614256650576692846
string str = "Hello 算法";
size_t hashStr = hash<string>()(str);
// 字符串 Hello 算法 的哈希值为 15466937326284535026
// 在 C++ 中,内置 std:hash() 仅提供基本数据类型的哈希值计算
// 数组、对象的哈希值计算需要自行实现
```
=== "Python"
```python title="built_in_hash.py"
@@ -331,28 +280,55 @@ $$
# 节点对象 <ListNode object at 0x1058fd810> 的哈希值为 274267521
```
=== "Go"
=== "C++"
```go title="built_in_hash.go"
```cpp title="built_in_hash.cpp"
int num = 3;
size_t hashNum = hash<int>()(num);
// 整数 3 的哈希值为 3
bool bol = true;
size_t hashBol = hash<bool>()(bol);
// 布尔量 1 的哈希值为 1
double dec = 3.14159;
size_t hashDec = hash<double>()(dec);
// 小数 3.14159 的哈希值为 4614256650576692846
string str = "Hello 算法";
size_t hashStr = hash<string>()(str);
// 字符串 Hello 算法 的哈希值为 15466937326284535026
// 在 C++ 中,内置 std:hash() 仅提供基本数据类型的哈希值计算
// 数组、对象的哈希值计算需要自行实现
```
=== "JS"
=== "Java"
```javascript title="built_in_hash.js"
// JavaScript 未提供内置 hash code 函数
```
```java title="built_in_hash.java"
int num = 3;
int hashNum = Integer.hashCode(num);
// 整数 3 的哈希值为 3
=== "TS"
boolean bol = true;
int hashBol = Boolean.hashCode(bol);
// 布尔量 true 的哈希值为 1231
```typescript title="built_in_hash.ts"
// TypeScript 未提供内置 hash code 函数
```
double dec = 3.14159;
int hashDec = Double.hashCode(dec);
// 小数 3.14159 的哈希值为 -1340954729
=== "C"
String str = "Hello 算法";
int hashStr = str.hashCode();
// 字符串 Hello 算法 的哈希值为 -727081396
```c title="built_in_hash.c"
Object[] arr = { 12836, "小哈" };
int hashTup = Arrays.hashCode(arr);
// 数组 [12836, 小哈] 的哈希值为 1151158
ListNode obj = new ListNode(0);
int hashObj = obj.hashCode();
// 节点对象 utils.ListNode@7dc5e7b4 的哈希值为 2110121908
```
=== "C#"
@@ -383,6 +359,12 @@ $$
// 节点对象 0 的哈希值为 39053774;
```
=== "Go"
```go title="built_in_hash.go"
```
=== "Swift"
```swift title="built_in_hash.swift"
@@ -411,10 +393,16 @@ $$
// 节点对象 utils.ListNode 的哈希值为 -2434780518035996159
```
=== "Zig"
=== "JS"
```zig title="built_in_hash.zig"
```javascript title="built_in_hash.js"
// JavaScript 未提供内置 hash code 函数
```
=== "TS"
```typescript title="built_in_hash.ts"
// TypeScript 未提供内置 hash code 函数
```
=== "Dart"
@@ -451,6 +439,18 @@ $$
```
=== "C"
```c title="built_in_hash.c"
```
=== "Zig"
```zig title="built_in_hash.zig"
```
在许多编程语言中,**只有不可变对象才可作为哈希表的 `key`** 。假如我们将列表(动态数组)作为 `key` ,当列表的内容发生变化时,它的哈希值也随之改变,我们就无法在哈希表中查询到原先的 `value` 了。
虽然自定义对象(比如链表节点)的成员变量是可变的,但它是可哈希的。**这是因为对象的哈希值通常是基于内存地址生成的**,即使对象的内容发生了变化,但它的内存地址不变,哈希值仍然是不变的。
+56 -56
View File
@@ -31,9 +31,9 @@
- 使用列表(动态数组)代替链表,从而简化代码。在这种设定下,哈希表(数组)包含多个桶,每个桶都是一个列表。
- 以下实现包含哈希表扩容方法。当负载因子超过 $0.75$ 时,我们将哈希表扩容至 $2$ 倍。
=== "Java"
=== "Python"
```java title="hash_map_chaining.java"
```python title="hash_map_chaining.py"
[class]{HashMapChaining}-[func]{}
```
@@ -43,9 +43,15 @@
[class]{HashMapChaining}-[func]{}
```
=== "Python"
=== "Java"
```python title="hash_map_chaining.py"
```java title="hash_map_chaining.java"
[class]{HashMapChaining}-[func]{}
```
=== "C#"
```csharp title="hash_map_chaining.cs"
[class]{HashMapChaining}-[func]{}
```
@@ -55,6 +61,12 @@
[class]{hashMapChaining}-[func]{}
```
=== "Swift"
```swift title="hash_map_chaining.swift"
[class]{HashMapChaining}-[func]{}
```
=== "JS"
```javascript title="hash_map_chaining.js"
@@ -67,30 +79,6 @@
[class]{HashMapChaining}-[func]{}
```
=== "C"
```c title="hash_map_chaining.c"
[class]{hashMapChaining}-[func]{}
```
=== "C#"
```csharp title="hash_map_chaining.cs"
[class]{HashMapChaining}-[func]{}
```
=== "Swift"
```swift title="hash_map_chaining.swift"
[class]{HashMapChaining}-[func]{}
```
=== "Zig"
```zig title="hash_map_chaining.zig"
[class]{HashMapChaining}-[func]{}
```
=== "Dart"
```dart title="hash_map_chaining.dart"
@@ -103,6 +91,18 @@
[class]{HashMapChaining}-[func]{}
```
=== "C"
```c title="hash_map_chaining.c"
[class]{hashMapChaining}-[func]{}
```
=== "Zig"
```zig title="hash_map_chaining.zig"
[class]{HashMapChaining}-[func]{}
```
值得注意的是,当链表很长时,查询效率 $O(n)$ 很差。**此时可以将链表转换为“AVL 树”或“红黑树”**,从而将查询操作的时间复杂度优化至 $O(\log n)$ 。
## 开放寻址
@@ -130,9 +130,9 @@
- 我们使用一个固定的键值对实例 `removed` 来标记已删除元素。也就是说,当一个桶内的元素为 $\text{None}$ 或 `removed` 时,说明这个桶是空的,可用于放置键值对。
- 在线性探测时,我们从当前索引 `index` 向后遍历;而当越过数组尾部时,需要回到头部继续遍历。
=== "Java"
=== "Python"
```java title="hash_map_open_addressing.java"
```python title="hash_map_open_addressing.py"
[class]{HashMapOpenAddressing}-[func]{}
```
@@ -142,9 +142,15 @@
[class]{HashMapOpenAddressing}-[func]{}
```
=== "Python"
=== "Java"
```python title="hash_map_open_addressing.py"
```java title="hash_map_open_addressing.java"
[class]{HashMapOpenAddressing}-[func]{}
```
=== "C#"
```csharp title="hash_map_open_addressing.cs"
[class]{HashMapOpenAddressing}-[func]{}
```
@@ -154,6 +160,12 @@
[class]{hashMapOpenAddressing}-[func]{}
```
=== "Swift"
```swift title="hash_map_open_addressing.swift"
[class]{HashMapOpenAddressing}-[func]{}
```
=== "JS"
```javascript title="hash_map_open_addressing.js"
@@ -166,30 +178,6 @@
[class]{HashMapOpenAddressing}-[func]{}
```
=== "C"
```c title="hash_map_open_addressing.c"
[class]{hashMapOpenAddressing}-[func]{}
```
=== "C#"
```csharp title="hash_map_open_addressing.cs"
[class]{HashMapOpenAddressing}-[func]{}
```
=== "Swift"
```swift title="hash_map_open_addressing.swift"
[class]{HashMapOpenAddressing}-[func]{}
```
=== "Zig"
```zig title="hash_map_open_addressing.zig"
[class]{HashMapOpenAddressing}-[func]{}
```
=== "Dart"
```dart title="hash_map_open_addressing.dart"
@@ -202,6 +190,18 @@
[class]{HashMapOpenAddressing}-[func]{}
```
=== "C"
```c title="hash_map_open_addressing.c"
[class]{hashMapOpenAddressing}-[func]{}
```
=== "Zig"
```zig title="hash_map_open_addressing.zig"
[class]{HashMapOpenAddressing}-[func]{}
```
### 多次哈希
顾名思义,多次哈希方法是使用多个哈希函数 $f_1(x)$、$f_2(x)$、$f_3(x)$、$\dots$ 进行探测。
+205 -205
View File
@@ -26,27 +26,27 @@
哈希表的常见操作包括:初始化、查询操作、添加键值对和删除键值对等。
=== "Java"
=== "Python"
```java title="hash_map.java"
/* 初始化哈希表 */
Map<Integer, String> map = new HashMap<>();
```python title="hash_map.py"
# 初始化哈希表
hmap: dict = {}
/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map.put(12836, "小哈");
map.put(15937, "小啰");
map.put(16750, "小算");
map.put(13276, "小法");
map.put(10583, "小鸭");
# 添加操作
# 在哈希表中添加键值对 (key, value)
hmap[12836] = "小哈"
hmap[15937] = "小啰"
hmap[16750] = "小算"
hmap[13276] = "小法"
hmap[10583] = "小鸭"
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
String name = map.get(15937);
# 查询操作
# 向哈希表输入键 key ,得到值 value
name: str = hmap[15937]
/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.remove(10583);
# 删除操作
# 在哈希表中删除键值对 (key, value)
hmap.pop(10583)
```
=== "C++"
@@ -72,27 +72,50 @@
map.erase(10583);
```
=== "Python"
=== "Java"
```python title="hash_map.py"
# 初始化哈希表
hmap: Dict = {}
```java title="hash_map.java"
/* 初始化哈希表 */
Map<Integer, String> map = new HashMap<>();
# 添加操作
# 在哈希表中添加键值对 (key, value)
hmap[12836] = "小哈"
hmap[15937] = "小啰"
hmap[16750] = "小算"
hmap[13276] = "小法"
hmap[10583] = "小鸭"
/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map.put(12836, "小哈");
map.put(15937, "小啰");
map.put(16750, "小算");
map.put(13276, "小法");
map.put(10583, "小鸭");
# 查询操作
# 向哈希表输入键 key ,得到值 value
name: str = hmap[15937]
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
String name = map.get(15937);
# 删除操作
# 在哈希表中删除键值对 (key, value)
hmap.pop(10583)
/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.remove(10583);
```
=== "C#"
```csharp title="hash_map.cs"
/* 初始化哈希表 */
Dictionary<int, String> map = new ();
/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map.Add(12836, "小哈");
map.Add(15937, "小啰");
map.Add(16750, "小算");
map.Add(13276, "小法");
map.Add(10583, "小鸭");
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
String name = map[15937];
/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.Remove(10583);
```
=== "Go"
@@ -118,6 +141,29 @@
delete(hmap, 10583)
```
=== "Swift"
```swift title="hash_map.swift"
/* 初始化哈希表 */
var map: [Int: String] = [:]
/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map[12836] = "小哈"
map[15937] = "小啰"
map[16750] = "小算"
map[13276] = "小法"
map[10583] = "小鸭"
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
let name = map[15937]!
/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.removeValue(forKey: 10583)
```
=== "JS"
```javascript title="hash_map.js"
@@ -167,64 +213,6 @@
console.info(map);
```
=== "C"
```c title="hash_map.c"
// C 未提供内置哈希表
```
=== "C#"
```csharp title="hash_map.cs"
/* 初始化哈希表 */
Dictionary<int, String> map = new ();
/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map.Add(12836, "小哈");
map.Add(15937, "小啰");
map.Add(16750, "小算");
map.Add(13276, "小法");
map.Add(10583, "小鸭");
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
String name = map[15937];
/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.Remove(10583);
```
=== "Swift"
```swift title="hash_map.swift"
/* 初始化哈希表 */
var map: [Int: String] = [:]
/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
map[12836] = "小哈"
map[15937] = "小啰"
map[16750] = "小算"
map[13276] = "小法"
map[10583] = "小鸭"
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
let name = map[15937]!
/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
map.removeValue(forKey: 10583)
```
=== "Zig"
```zig title="hash_map.zig"
```
=== "Dart"
```dart title="hash_map.dart"
@@ -254,24 +242,33 @@
```
=== "C"
```c title="hash_map.c"
// C 未提供内置哈希表
```
=== "Zig"
```zig title="hash_map.zig"
```
哈希表有三种常用遍历方式:遍历键值对、遍历键和遍历值。
=== "Java"
=== "Python"
```java title="hash_map.java"
/* 遍历哈希表 */
// 遍历键值对 key->value
for (Map.Entry <Integer, String> kv: map.entrySet()) {
System.out.println(kv.getKey() + " -> " + kv.getValue());
}
// 单独遍历键 key
for (int key: map.keySet()) {
System.out.println(key);
}
// 单独遍历值 value
for (String val: map.values()) {
System.out.println(val);
}
```python title="hash_map.py"
# 遍历哈希表
# 遍历键值对 key->value
for key, value in hmap.items():
print(key, "->", value)
# 单独遍历键 key
for key in hmap.keys():
print(key)
# 单独遍历值 value
for value in hmap.values():
print(value)
```
=== "C++"
@@ -292,19 +289,40 @@
}
```
=== "Python"
=== "Java"
```python title="hash_map.py"
# 遍历哈希表
# 遍历键值对 key->value
for key, value in hmap.items():
print(key, "->", value)
# 单独遍历键 key
for key in hmap.keys():
print(key)
# 单独遍历值 value
for value in hmap.values():
print(value)
```java title="hash_map.java"
/* 遍历哈希表 */
// 遍历键值对 key->value
for (Map.Entry <Integer, String> kv: map.entrySet()) {
System.out.println(kv.getKey() + " -> " + kv.getValue());
}
// 单独遍历键 key
for (int key: map.keySet()) {
System.out.println(key);
}
// 单独遍历值 value
for (String val: map.values()) {
System.out.println(val);
}
```
=== "C#"
```csharp title="hash_map.cs"
/* 遍历哈希表 */
// 遍历键值对 Key->Value
foreach (var kv in map) {
Console.WriteLine(kv.Key + " -> " + kv.Value);
}
// 单独遍历键 key
foreach (int key in map.Keys) {
Console.WriteLine(key);
}
// 单独遍历值 value
foreach (String val in map.Values) {
Console.WriteLine(val);
}
```
=== "Go"
@@ -325,6 +343,24 @@
}
```
=== "Swift"
```swift title="hash_map.swift"
/* 遍历哈希表 */
// 遍历键值对 Key->Value
for (key, value) in map {
print("\(key) -> \(value)")
}
// 单独遍历键 Key
for key in map.keys {
print(key)
}
// 单独遍历值 Value
for value in map.values {
print(value)
}
```
=== "JS"
```javascript title="hash_map.js"
@@ -361,54 +397,6 @@
}
```
=== "C"
```c title="hash_map.c"
// C 未提供内置哈希表
```
=== "C#"
```csharp title="hash_map.cs"
/* 遍历哈希表 */
// 遍历键值对 Key->Value
foreach (var kv in map) {
Console.WriteLine(kv.Key + " -> " + kv.Value);
}
// 单独遍历键 key
foreach (int key in map.Keys) {
Console.WriteLine(key);
}
// 单独遍历值 value
foreach (String val in map.Values) {
Console.WriteLine(val);
}
```
=== "Swift"
```swift title="hash_map.swift"
/* 遍历哈希表 */
// 遍历键值对 Key->Value
for (key, value) in map {
print("\(key) -> \(value)")
}
// 单独遍历键 Key
for key in map.keys {
print(key)
}
// 单独遍历值 Value
for value in map.values {
print(value)
}
```
=== "Zig"
```zig title="hash_map.zig"
```
=== "Dart"
```dart title="hash_map.dart"
@@ -435,6 +423,18 @@
```
=== "C"
```c title="hash_map.c"
// C 未提供内置哈希表
```
=== "Zig"
```zig title="hash_map.zig"
```
## 哈希表简单实现
我们先考虑最简单的情况,**仅用一个数组来实现哈希表**。在哈希表中,我们将数组中的每个空位称为「桶 bucket」,每个桶可存储一个键值对。因此,查询操作就是找到 `key` 对应的桶,并在桶中获取 `value` 。
@@ -458,9 +458,9 @@ index = hash(key) % capacity
以下代码实现了一个简单哈希表。其中,我们将 `key` 和 `value` 封装成一个类 `Pair` ,以表示键值对。
=== "Java"
=== "Python"
```java title="array_hash_map.java"
```python title="array_hash_map.py"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
@@ -474,9 +474,17 @@ index = hash(key) % capacity
[class]{ArrayHashMap}-[func]{}
```
=== "Python"
=== "Java"
```python title="array_hash_map.py"
```java title="array_hash_map.java"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
```
=== "C#"
```csharp title="array_hash_map.cs"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
@@ -490,38 +498,6 @@ index = hash(key) % capacity
[class]{arrayHashMap}-[func]{}
```
=== "JS"
```javascript title="array_hash_map.js"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
```
=== "TS"
```typescript title="array_hash_map.ts"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
```
=== "C"
```c title="array_hash_map.c"
[class]{pair}-[func]{}
[class]{arrayHashMap}-[func]{}
```
=== "C#"
```csharp title="array_hash_map.cs"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
```
=== "Swift"
```swift title="array_hash_map.swift"
@@ -539,9 +515,17 @@ index = hash(key) % capacity
[class]{ArrayHashMap}-[func]{}
```
=== "Zig"
=== "JS"
```zig title="array_hash_map.zig"
```javascript title="array_hash_map.js"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
```
=== "TS"
```typescript title="array_hash_map.ts"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
@@ -563,6 +547,22 @@ index = hash(key) % capacity
[class]{ArrayHashMap}-[func]{}
```
=== "C"
```c title="array_hash_map.c"
[class]{pair}-[func]{}
[class]{arrayHashMap}-[func]{}
```
=== "Zig"
```zig title="array_hash_map.zig"
[class]{Pair}-[func]{}
[class]{ArrayHashMap}-[func]{}
```
## 哈希冲突与扩容
本质上看,哈希函数的作用是将所有 `key` 构成的输入空间映射到数组所有索引构成的输出空间,而输入空间往往远大于输出空间。因此,**理论上一定存在“多个输入对应相同输出”的情况**。