JavaScript实现哈希表数据结构以及部分方法的封装

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
}

哈希表的大致的数据结构

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值