封装哈希表结构:
//封装哈希表类
function HashTable(){
//属性
this.storage = [];
this.count = 0;
this.limit = 7;
//方法
//哈希函数
HashTable.prototype.hashFunc = function (str,size){
//1.定义hashCode变量
var hashCode = 0;
//2.霍纳算法,计算hashCode的值
//cats -> Unicode编码
for(var i = 0;i < str.length;i++){
hashCode = 37 * hashCode + str.charCodeAt(i);
}
//3.取余操作
var index = hashCode % size;
return index;
}
//插入&修改操作
HashTable.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++;
//6.判断是否进行扩容操作
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){
//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.有bucket,那么进行线性查找
for(var i = 0; i < bucket.length; i++) {
var tuple = bucket[i];
if(tuple[0] == key){
return tuple[1]
}
}
//5.依然没有找到,返回null
return null;
}
// 删除操作
HashTable.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.有bucket,那么就进行线性查找,并删除
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 = this.limit / 2;
var newPrime = this.getPrime(newSize)
this.resize(newPrime);
}
//返回
return tuple[1];
}
}
//5.如果依然没有找到,返回Null
return null;
}
//其它方法
//判断哈希表是否为空
HashTable.prototype.isEmpty = function(){
return this.count === 0;
}
//获取哈希表中元素个数
HashTable.prototype.size = function(){
return this.count;
}
//哈希表扩容
HashTable.prototype.resize = function (newLimit){
//1.保存旧的数组内容
var oldStroge = this.storage;
//2.重置所有的属性
this.storage = [];
this.count = 0;
this.limit = newLimit;
//3.遍历oldStorage中所有的bucket
for(var i = 0; i < oldStroge.length; i++){
//3.1取出对应的bucket
var bucket = oldStroge[i];
//3.2判断bucket是否为null
if(bucket == null){
continue
}
//3.3bucket中有数据,那么取出数据,重新插入
for(var j = 0;j < bucket.length; j++){
var tuple = bucket[j];
this.put(tuple[0],tuple[1]);
}
}
}
//判断某个数字是否是质数
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;
}
}