[数据结构学习笔记11] 哈希表(Hashtable)
哈希表也叫Hashmap或者Dictionary,它存储和检索都非常快,所以常用于缓存数据供后续快速访问。
哈希函数,是这样的一个函数,你提供一个input,它会返回一个唯一的值(hash code)。只要你的input是相同的,这个哈希函数会返回同样的output。
从哈希函数到哈希表
哈希表底层是一个数组结构,这意味着往哈希表加元素,检索元素所需的时间都是O(1)。
往哈希表中添加元素
1. Key:标识符,可供后续指向数值
2. Value:具体我们要存的数据
比如[key, value]
Link, 123-4567
Zelda, 234-5678
Mario, 345-5679
存放:
Link |
hashing function |
0 | 234-5678 |
Zelda | 1 | ||
Mario | 2 | 123-4567 | |
3 | 345-5679 | ||
4 |
读取的时候,比如我们想读Link,那么hashing function会直接计算,得到index 2,从而直接得到Link的号码。如果你想找Batman,它不在这个key列表里,那就不存在了。
几乎所有高级语言都有哈希表的实现,javascript里是Map。
let characterInfo = new Map(); characterInfo.set("Link", "123-4567"); characterInfo.set("Zelda", "234-5678"); characterInfo.set("Mario", "345-5679"); // get values console.log(characterInfo.get("Link")); // 123-4567 console.log(characterInfo.get("Batman")); // undefined // get size console.log(characterInfo.size()); // 3 // delete item characterInfo.delete("Mario"); // delete all items characterInfo.clear();
在这背后,有个hashing function帮我们快速的关联key和存储的位置。这个hashing function长什么样子呢?看看下面一个例子:
function hash(key, arraySize) { let hashValue = 0; for (let i = 0; i < key.length; i++) { hashValue += key.charCodeAt(i); } return hashValue % arraySize; } // Create a new array allocated for 100 items let myArray = new Array(100); let myHash = hash("Ryu", myArray.length); // myHash = 20;
如果我们想存超过100 size的数据呢,这里会报错。
但是还有一种情况:
let newHash = hash("Yur", myArray.length); // myHash = 20
这里不同的key,计算出了相同的值。这种情况称为冲突。
理想情况下,我们的哈希函数满足两个条件:
1. 任意一个唯一的input,给它生成唯一的output
2. 有足够的存储来存放计算出来的每个位置
实际上,这两个条件都可能会满足不了。这时候就是哈希冲突。哈希冲突,可能会让同一个地址里,存放多个值。哈希冲突有一些解决的方法,在这里先不讨论了。:)
时间复杂度
理想情况下,如果没有哈希冲突,存取都是O(1);但是如果有哈希冲突,很多值存放在同一个地址时,时间会变成O(n)。这种通常是哈希函数设计不好,我们要避免这样的情况。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验