class HashTable {
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的所有的bucket
for (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)return false
}
return true
}
//获取质数的方法
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) {
return false
}
// 遍历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,则返回false
return false
}
JavaScript实现哈希表数据结构以及部分方法的封装
最新推荐文章于 2022-06-17 17:01:49 发布