只给代码,原理不做阐述
//设计哈希函数
//将字符串转化成较大的数字: hashcode
//将hashcode压缩到数组范围内
function hashFunc(str,size) {
let hashcode = 0
//霍纳算法来计算 hashcode的值
for (let i = 0; i < str.length; i++) {
hashcode = 37 * hashcode + str.charCodeAt(i)
}
let index = hashcode % size //压缩
return index
}
//哈希表的实现
function HashForm() {
this.storage = []
this.count = 0 //当前存储的个数
this.limit = 7 //数组的最大长度
//1、哈希函数
HashForm.prototype.hashFunc = function (str,size) {
let hashcode = 0
//霍纳算法来计算 hashcode的值
for (let i = 0; i < str.length; i++) {
hashcode = 37 * hashcode + str.charCodeAt(i)
}
let index = hashcode % size //压缩
return index
}
//2、插入和修改
HashForm.prototype.put = function (key,value) {
//根据key获取对应的index
let index = this.hashFunc(key,this.limit)
//根据index 取出对应的bucket
let bucket = this.storage[index]
//判断bucket是否存在
if (bucket === undefined) {
bucket = []
this.storage[index] = bucket
}
//判断是否修改数据
for (let i = 0; i < bucket.length; i++) {
let tuple = bucket[i]
if (tuple[0] === key) {
tuple[1] = value
return
}
}
//添加数据
bucket.push([key,value])
this.count += 1
//判断是否需要扩容
if (this.count > this.limit * 0.75) {
let newSize = this.limit * 2
let newPrime = this.getPrime(newSize) // 容量为质数 是数据分布的更加均匀
this.resize(newPrime)
}
}
//3、获取操作
HashForm.prototype.get = function (key) {
//根据key获取对应的index
let index = this.hashFunc(key,this.limit)
//根据index 取出对应的bucket
let bucket = this.storage[index]
//判断bucket是否存在
if (bucket === undefined) { //要获取的值不存在 直接返回null
return null
}
//线性查找
for (let i = 0; i < bucket.length; i++) {
let tuple = bucket[i]
if (key === tuple[0]) {
return tuple[1]
}
}
return null
}
//4、删除操作
HashForm.prototype.remove = function (key) {
//根据key获取对应的index
let index = this.hashFunc(key,this.limit)
//根据index 取出对应的bucket
let bucket = this.storage[index]
//判断bucket是否存在
if (bucket === undefined) {
return null
}
//线性查找
for (let i = 0; i < bucket.length;i++) {
let tuple = bucket[i]
if (key === tuple[0]) {
bucket.splice(i,1)
this.count -= 1
return tuple[1]
//缩小容量
if (this.limit > 7 && this.count < this.limit * 0.25) {
let newSize = Math.floor(this.limit / 2)
let newPrime = this.getPrime(newSize) // 容量为质数 是数据分布的更加均匀
this.resize(newPrime)
}
}
}
//没有找到 返回null
return null
}
//isEmpty
HashForm.prototype.isEmpty = function () {
return this.count === 0
}
//获取个数
HashForm.prototype.size = function () {
return this.count
}
//扩容
HashForm.prototype.resize = function (newLimit) {
let oldStorage = this.storage
this.storage = []
this.count = 0
this.limit = newLimit
//扩容需要将原先所有的数据取出 插入到新扩容到数组中
for (let i = 0 ; i < oldStorage.length; i++) {
let bucket = oldStorage[i]
if (bucket === undefined) { //为空 没有数据 继续下一个
continue
}
for (let j = 0; j < bucket.length; i++) {
let tuple = bucket[i]
this.put(tuple[0],tuple[1])
}
}
}
//判断质数
HashForm.prototype.isPrime = function (num) {
let temp = parseInt(Math.sqrt(num))
for (let i = 2; i < temp; i++) {
if (num % i === 0) {
return false
}
}
return true
}
//获取质数
HashForm.prototype.getPrime = function (num) {
while (!this.isPrime(num)) {
num++
}
return num
}
}
const HF = new HashForm()
HF.put('aa','123')
HF.put('bb','189')
HF.put('cc','289')
HF.put('dd','389')
console.log(HF);
console.log(HF.get('aa'));
HF.put('aa','456')
console.log(HF.get('aa'));
console.log(HF.size())
console.log(HF.remove('aa'));
console.log(HF.size())