classHashTable{constructor(){// storage为数组,采用拉链法(效率更高),数组中存放另一数组,另一数组中保存的key和value值即是真正的想要存放数据,整个哈希表类似于二维数组的结构this.storage =[];// count用来表示已经数组中存放了多少数据this.count =0;// limit表示哈希表的总长度this.limit =7// 填装因子:哈希表中存放的数据个数/哈希表的长度,可以大于1,当填装因子大于0.75需要扩容,小于0.25需要削减长度}}//哈希函数
HashTable.prototype.hashFunc = function (str, size){
var hashCode =0;for(vari =0; i < str.length; i++){
hashCode =37* hashCode + str.charCodeAt(i)}
var index = hashCode % size;return index
}// 扩容和缩小容量的操作// newLimit:哈希表扩容之后的总长度
HashTable.prototype.resize = function (newLimit){// 保存旧的数组的内容
var oldStorage =this.storage;// 将原数组中的属性重置this.storage =[];this.count =0;this.limit = newLimit;// 遍历oldStorage的所有的bucketfor(var i =0; i < oldStorage.length; i++){//取出oldStorage中的bucket
var bucket = oldStorage[i];//判断bucket是否为空if(bucket == null)continue;//遍历取出bucket中的key和value值for(var j =0; j < bucket.length; j++){
var tuple = bucket[j];//将key和value值重新插入到bucket中去this.put([tuple[0], tuple[1]])}}}//判断某个数字是否为质数(平方根方式)
HashTable.prototype.isPrime=function(num){
var t=parseInt(Math.sqrt(num));for(var i=2;i<t;i++){if(n%t==0)returnfalse}returntrue}//获取质数的方法
HashTable.prototype.getPrime=function(num){while(!this.isPrime(num)){
num++}return num;}// 1.插入和修改操作
HashTable.prototype.put = function (key, value){// 根据key关键字通过哈希函数转换成索引值
var index =this.hashFunc(key,this.limit);//根据索引值取出在索引值位置的存放真正数据的数组的数组
var bucket =this.storage[index];//判断bucket是否为空if(bucket == null){
bucket =[];this.storage[index]= bucket
}//判断是否是修改数据,遍历bucket数组查找key值for(var i =0; x < bucket.length; x++){//tuple即为存放key和value的数组
var tuple = bucket[i];// 执行修改操作,哈希表中的key值是唯一的if(tuple[0]== key){
tuple[1]= value
}}//找不到则执行添加操作
bucket.push([key, value]);this.count +=1;// 判断是否需要扩容操作if(this.count >this.limit *0.75){
var newSize=this.limit*2;
var prime=this.getPrime(newSize)this.resize(prime)}}// 2.查询操作
HashTable.prototype.get = function (key){// 根据key关键字通过哈希函数转换成索引值
var i =this.hashFunc(key,this.limit);//根据索引值取出在索引值位置的存放真正数据的数组的数组
var bucket =this.storage[i];//判断bucket是否为空if(bucket == null){return null
}// 遍历bucket中的元素for(var i =0; i < bucket.length; i++){
var tuple = bucket[i];if(tuple[0]== key){return tuple[1]}}// 如果上述步骤未找到,则返回空return null
}// 3.删除操作
HashTable.prototype.delete = function (key){// 根据key关键字通过哈希函数转换成索引值
var i =this.hashFunc(key,this.limit);//根据索引值取出在索引值位置的存放真正数据的数组的数组
var bucket =this.storage[i];//判断bucket是否为空if(bucket == null){returnfalse}// 遍历bucket中的元素for(var i =0; i < bucket.length; i++){
var tuple = bucket[i];if(key == tuple[0]){
bucket.splice(i,1);this.count--;}}// 判断是否需要减小容量if(this.limit >7&&this.count <0.25*this.limit){
var newSize=this.limit*2;
var prime=this.getPrime(newSize)this.resize(prime)}// 如果上述步骤未找到key,则返回falsereturnfalse}