//封装哈希表
function hashTable(){
// 属性
this.storage = []
this.count = 0
this.limit = 7
// 设计哈希函数
// 将字符串转换成比较大的数字:hashCode
// 将大的数字hashCode压缩到数组范围(大小)之内
hashTable.prototype.hashFunc = function(str,size){
let hashCode = 0
for(let i=0;i<str.length;i++){
hashCode = 37*hashCode + str.charCodeAt(i)
}
let index = hashCode%size
return index
}
//插入&修改操作
// 1.根据key获取对应的index
// 2.根据index获取对应的bucket,如果没有则创建
// 3.判断新增还是修改,如果有值就是修改,如果没值就是新增
hashTable.prototype.put = function(key,value){
let index = this.hashFunc(key,this.limit)
let bucket = this.storage[index]
if(bucket == null){
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++
//如果count>limit*0.75,进行扩容
if(this.count > this.limit*0.75){
let newSize = this.limit*2
let newPrime = this.getPrime(newSize)
this.resize(newPrime)
}
}
//获取操作
// 1.根据key获取对应的index
// 2.根据index获取对应的bucket,如果没有 return null
// 3.遍历bucket,如果有key返回value,如果没有返回null
hashTable.prototype.get = function(key){
let index = this.hashFunc(key,this.limit)
let bucket = this.storage[index]
if(bucket == null){
return null
}
for(let i=0;i<bucket.length;i++){
let tuple = bucket[i]
if(tuple[0] == key){
return tuple[1]
}
}
return null
}
//删除操作 步骤与获取类似
hashTable.prototype.remove = function(key){
let index = this.hashFunc(key,this.limit)
let bucket = this.storage[index]
if(bucket == null) return null
for(let i=0;i<bucket.length;i++){
let tuple = bucket[i]
if(tuple[0] == key){
bucket.splice(i,1)
this.count--
//如果count<this.limit*0.25,缩小容量
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)
}
return tuple[1]
}
}
return null
}
hashTable.prototype.isEmpty = function(){
return this.count == 0
}
hashTable.prototype.size = function(){
return this.count
}
// 哈希表扩容&缩容
// 1.保存旧数组,重置所有属性
// 2.遍历旧数组,将bucket中的元素重新放到新的哈希表中
hashTable.prototype.resize = function(newLimit){
let oldSorage = this.storage
this.storage = []
this.count = 0
this.limit = newLimit
for(let i=0;i<oldSorage.length;i++){
let bucket = oldSorage[i]
if(bucket == null) continue
for(let j=0;j<bucket.length;j++){
let tuple = bucket[j]
this.put(tuple[0],tuple[1])
}
}
}
//判断质数,用于扩容时容量大小的计算
hashTable.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
}
hashTable.prototype.getPrime = function(num){
while(!this.isPrime(num)){
num++
}
return num
}
}
哈希表的封装
最新推荐文章于 2022-09-05 22:30:32 发布