![]()
![]()
![]()
function HashTable() {
this.storage = []
this.count = 0
this.limit = 7
// 哈希函数
HashTable.prototype.hashFunc = function (str,size) {
var hashCode = 0
for(var i=0; i<str.length; i++) {
hashCode = 37 * hashCode + str.charCodeAt(i)
}
index = hashCode % size
return index
}
// 插入修改操作
HashTable.prototype.put = function(key,value) {
// 根据key获取索引值 将数据插入到对应的位置
// 根据索引值 取出bucket(桶)
// 如果桶不存在创建桶 放置在该索引的位置
// 判断是新增还是修改原来的值
var index = this.hashFunc(key,this.limit)
var bucket = this.storage[index]
if(bucket == null) {
bucket = []
this.storage[index] = bucket
}
// 判断是否是修改
for (var i=0; i< bucket.length; i++) {
var 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) {
var newSize = this.limit * 2
var newPrime = this.getPrime(newSize)
this.resize(newPrime)
}
}
HashTable.prototype.get = function(key) {
//根据key获取对应的index 根据index 获取对应的bucket
//判断bucket如果为null直接返回null
//线性的查找bucket中每一个key是否等于传入的key
var index = this.hashFunc(key,this.limit)
var bucket = this.storage[index]
if(bucket == null) {
return null
}
// 有值 线性查找
for (var i=0; i< bucket.length; i++) {
var tuple = bucket[i]
if (tuple[0] == key) {
return tuple[1]
}
}
return null
}
HashTable.prototype.remove = function(key) {
//根据key获取对应的index 根据index 获取对应的bucket
//判断bucket如果不存在直接返回null
//线性的查找bucket中每一个key是否等于传入的key 并且删除
var index = this.hashFunc(key,this.limit)
var bucket = this.storage[index]
if(bucket == null) {
return null
}
// 有值 线性查找 删除
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) {
var newSize = Math.floor(this.limit / 2)
var 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
}
HashTable.prototype.resize = function(newLimit) {
// 保存旧的数组内容
var oldStorage = this.storage
//
this.storage = []
this.count = 0
this.limit = newLimit
// 遍历oldStorage中所有bucket
for(var i=0; i<oldStorage.length; i++) {
var bucket = oldStorage[i]
if (bucket == null) {
continue
}
for(var j=0; j<bucket.length; j++) {
var tuple = bucket[j]
this.put(tuple[0],tuple[1]) //key,value重新插入新的数组
}
}
}
// 判断是否为质数
HashTable.prototype.isPrime = function(num) {
var temp = parseInt(Math.sqrt(num)) //开平方
for (var 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
}
}
var ht = new HashTable()
ht.put('abc','123')
ht.put('cba','321')
ht.put('nba','521')
alert(ht.get('abc'))
ht.put('abc','111')
alert(ht.get('abc'))
ht.remove('abc')
alert(ht.get('abc'))