一. 优秀的哈希函数

1.快速的计算: 需要快速的计算来获得对应的hashCode(霍纳法则来减少乘除次数)
2.均匀的分布: 尽可能将元素映射到不同的位置,让元素在哈希表中均匀分布

二.哈希表的扩容

三.哈希函数的实现


// 封装哈希表
function HashMap() {
//属性
this.storage = [] //存储数据
this.count = 0 //插入元素数量
this.limit = 7 //数组容量 //方法
//哈希函数
HashMap.prototype.hashFunc = function (str, size) {
//定义hashCode
var hashCode = 0
for (var i =0; i < str.length ; i++) {
hashCode = 37*hashCode + str.charCodeAt(i)
}
var index = hashCode % size
return index
} // 插入&修改
HashMap.prototype.put =function(key, value) {
// 1.根据key获取对应的index
var index = this.hashFunc(key, this.limit)
// 2.根据index取出对应的bucket
var bucket = this.storage[index]
// 3.判断bucket是否为null
if (bucket == null) {
bucket = []
this.storage[index] = bucket
}
// 4.判断是否是修改数据
for (var i = 0; i< bucket.length; i++) {
var tuple = bucket[i]
if (tuple[0] == key) {
tuple[1] = value
return
}
}
// 5.进行添加操作
bucket.push([key, value])
this.count += 1 //扩容
if (this.count > this.limit * 0.75) {
this.resize(this.limit * 2)
}
} //获取操作
HashMap.prototype.get =function(key) {
// 1.根据key获取对应的index
var index = this.hashFunc(key, this.limit)
// 2.根据index取出对应的bucket
var bucket = this.storage[index]
// 3.判断bucket是否为null
if (bucket == null) {
return null
}
// 4.判断是否存在数据
for (var i = 0; i< bucket.length; i++) {
var tuple = bucket[i]
if (tuple[0] == key) {
return tuple[1]
}
}
return null
}
//删除操作
HashMap.prototype.remove =function(key) {
// 1.根据key获取对应的index
var index = this.hashFunc(key, this.limit)
// 2.根据index取出对应的bucket
var bucket = this.storage[index]
// 3.判断bucket是否为null
if (bucket == null) {
return null
}
// 4.判断是否存在数据
for (var i = 0; i< bucket.length; i++) {
var tuple = bucket[i]
if (tuple[0] == key) {
bucket.splice(i , 1)
this.count--
if (this.limit > 7 && this.count < this.limit *0.25) {
thiss.resize(Math.floor(this.limit / 2))
}
return tuple[1]
}
}
return null
}
// 其他方法
//isEmpty方法
HashMap.prototype.isEmpty = function() {
return this.count == 0
}
//size方法
HashMap.prototype.size = function() {
return this.count
} //数组扩容或缩容
HashMap.prototype.resize = function(newLimit) {
//保存所有属性
var oldStorage = this.storage
//重置所有属性
this.count = 0
this.limit = newLimit
this.storage = []
//遍历oldStorage中所有的bucket
for (var i = 0; i < oldStorage.length; i++) {
var bucket = oldStorage[i]
if (bucket == null) {
continue
}
for (var j = 0; i< bucket.length; j++) {
var tuple = bucket[j]
this.put(tuple[0], tuple[1])
}
}
}
}

(js描述的)数据结构[哈希表1.2](9)的更多相关文章

  1. (js描述的)数据结构[哈希表1.1](8)

    (js描述的)数据结构[哈希表1.1](8) 一.数组的缺点 1.数组进行插入操作时,效率比较低. 2.数组基于索引去查找的操作效率非常高,基于内容去查找效率很低. 3.数组进行删除操作,效率也不高. ...

  2. (js描述的)数据结构[哈希表1.3](10)

    1.哈希表的完善 1.容量质数(limit):需要恒为质数,来确保元素的均匀分布. 1)普通算法: 判断一个数是否为质数 function isPrime(num) { for (var i = 2; ...

  3. (js描述的)数据结构[队列结构,优先级队列](3)

    (js描述的)数据结构[队列结构](3) 一.队列结构的特点: 1.基于数组来实现,的一种受限的线性结构. 2.只允许在表头进行删除操作,在表尾进行插入操作. 3.先进先出(FIFO) 二.队列的一些 ...

  4. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  5. (js描述的)数据结构[字典](7)

    (js描述的)数据结构[字典](7) 一.字典的特点 1.字典的主要特点是一一对应关系. 2.使用字典,剋通过key取出对应的value值. 3.字典中的key是不允许重复的,而value值是可以重复 ...

  6. (js描述的)数据结构[集合结构](6)

    (js描述的)数据结构[集合结构](6) 一.集合结构特点 1.集合中的元素不能重复. 2.集合是无序的. 二.集合的代码实现 function Set() { this.items = {} //1 ...

  7. (js描述的)数据结构[双向链表](5)

    (js描述的)数据结构[双向链表](5) 一.单向链表的缺点 1.只能按顺序查找,即从上一个到下一个,不能反过来. 二.双向链表的优点 1.可以双向查找 三.双向链表的缺点 1.结构较单向链表复杂. ...

  8. (js描述的)数据结构[链表](4)

    (js描述的)数据结构 [链表](4) 一.基本结构 二.想比于数组,链表的一些优点 1.内存空间不是必须连续的,可以充分利用计算机的内存,事项灵活的内存动态管理. 2.链表不必再创建时就确定大小,并 ...

  9. (js描述的)数据结构[栈结构](2)

    (js描述的)数据结构[栈结构](2) 一.什么是栈结构 1.一种受限制的线性结构,这种结构可以基于数组来实现. 2.可以抽象成一个容器,上面的是栈顶,底下的是栈底.所以仅允许对栈顶进行操作, 二.栈 ...

随机推荐

  1. Echart饼形图和折线图的循环展示及选择展示

    需求:根据不同的入参调同一接口,循环展示一组饼形图或折线图: 主要问题:在于给定的数据格式不符合图表的配置项格式,需要拆分组装数据:首先默认展示几个图表,当选中一个类别,需要展示其中一个的时候,页面中 ...

  2. go极其ide的安装

    一.下载软件开发包 官网:https://golang.google.cn/ 二.   安装和配置SDK windows使用.msi一键安装 配置环境变量 GOROOT,自动的,默认将go安装到C:/ ...

  3. Windows通过VNC连接并显示Linux桌面(Ubuntu16.04)

    目录 Linux中安装VNC服务 Linux中安装桌面环境 Windows中安装VNC Viewer Linux中安装VNC服务 sudo apt-get update sudo apt-get in ...

  4. 【分布式锁】02-使用Redisson实现公平锁原理

    前言 前面分析了Redisson可重入锁的原理,主要是通过lua脚本加锁及设置过期时间来保证锁执行的原子性,然后每个线程获取锁会将获取锁的次数+1,释放锁会将当前锁次数-1,如果为0则表示释放锁成功. ...

  5. mysql & Tomcat使用问题记录

    mysql使用问题记录 1.mysql如何修改root密码 a.进入mysql安装目录b.登录 mysql -u root -pc.修改密码 mysql> SET PASSWORD FOR ro ...

  6. 欲善事先利器-IEAD插件篇

    工欲善其事,必先利其器,好鞋踢好球是非常合乎逻辑的事情. --<长江七号> 同样的开场白,不一样的酒,不一样的故事. 上篇<欲善事先利器--系统篇>已经推荐了一些个人常用的效率 ...

  7. 如何区分前端BUG和后台BUG?

    测试工程师不只是负责发现问题,除了发现问题这种基本功外,定位问题,提出解决方案,提出预防方案也是要掌握的技能.这里先说定位问题的要求,定位问题要向深入,前提当然是对功能.产品的流程.开发方案.开发人员 ...

  8. Spring框架——AOP

    Spring AOP 面向切面编程,OOP面向对象编程,将程序中所有参与模块都抽象成对象,然后通过对象之间的相互调用完成需求. AOP是OOP的一种补充,是在另外一个维度上抽象出对象,具体是指程序运行 ...

  9. 洛谷 P1438 无聊的数列 题解

    原题链接 首先,我们考虑用差分解决问题. 用 \(x_i\) 表示原数列,\(a_i = x_i - x_{i-1}\) 那么,先普及一下差分: 如果我们只需要维护区间加值,单点求值的话,你会发现两个 ...

  10. [BFS,A*,k短路径] 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛 path (Problem - 6705)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6705 path Time Limit: 2000/2000 MS (Java/Others)    Mem ...