文章目录
前言
一、什么是散列表
散列表是字典(Dictionary)
的一种实现.
集合以[值, 值]
形式存储, 字典则以[键, 值]
对形式, 其中键名用于查询, 字典也称作映射
, 符号表
或关联数组
.
JavaScript
中允许使用方括号获取对象的属性, 将属性名作为"位置"传入即可, 常见的用法:
const obj = {
key: 'val';
}
console.log(obj[key]);
在ECMAScript2015
也就是ES6
中实现了Map
, 即此处字典结构.
虽然ES6
的Map
可以使用String
以外的类型作键(因为Map
可以基于分别存储键和值的两个数组及其方法实现, 内部的结构是可预测的, 这也是它iterable
的原因), 但是理想的字典结构应该使用String
类型作键, 这会让查找变得更简单.
参考现实中的字典, 应当具备单词及其释义, 还有一套查找目录, 为了在字典中快速检索值, 将一个key
(单词)作为索引, 为了保存信息依旧需要原始的key
(单词), 因此他不能只是一个简单的对象的结构, 不能是这样:
{
key1: 'val1',
key2: 'val2',
key3: 'val3',
key4: 'val4'
}
应为:
{
key1: {
key1: 'val1' },
key2: {
key2: 'val2' },
key3: {
key3: 'val3' },
key4: {
key1: 'val4' }
}
table作为字典:
字典中解释单词的视觉体验基本是一个大写的单词后面跟着释义.
你可以把最外层的key
看作用来给目录查找的索引, 找到之后, 这个对象的key
作为单词大写, 后面值作为释义.
二、为何使用散列算法
要在数据结构中找到一个值, 采用迭代整个数组来应对, 时间复杂度为O(n)
, n
为键值对的数量, 需要检查每一个键值对的匹配情况.
而如果使用散列函数就知道值的具体位置, 快速检索到该值. 散列函数的作用是给定一个键值, 然后返回该值在表中的位置, 参考上方典型的Dictionary
数据结构.
在关系型数据库(比如MySQL)中创建一个新的表时, 也可以通过创建索引来更快的查询到记录的key
.
JavaScript
语言内部也使用散列表来表示每个对象, 此时对象上的方法和属性被存储为key
对象类型, 每个key
指向对应的对象成员
我大胆猜测是这样的:
{
pro: {
pro: 'val' },
add: {
add: f() },
peek: {
peek: f() }
}
参考第一章典型字典结构的举例.
三、实现散列算法
目标是建立一个人名与邮箱对应的散列表, 索引会是人名字母转ASCII之和, 但是为了保存数据, 内部的键仍需为人名, 会是这样的结构:
{
'685': {
'Gandalf': 'gandalf@email.com' },
'399': {
'John': 'johnsnow@email.com' },
'645': {
'Tyrion': 'tyrion@email.com' },