javascript手动写代码实现哈希表(拉链法)

只给代码,原理不做阐述

//设计哈希函数
//将字符串转化成较大的数字: hashcode
//将hashcode压缩到数组范围内
function hashFunc(str,size) {

    let hashcode = 0
     //霍纳算法来计算 hashcode的值
    for (let i = 0; i < str.length; i++) {
        hashcode = 37 * hashcode + str.charCodeAt(i)
    }

    let index  = hashcode % size //压缩
    return index
}


//哈希表的实现
function HashForm() {
    this.storage = []
    this.count = 0 //当前存储的个数
    this.limit = 7 //数组的最大长度

    //1、哈希函数
    HashForm.prototype.hashFunc = function (str,size) {

        let hashcode = 0
        //霍纳算法来计算 hashcode的值
        for (let i = 0; i < str.length; i++) {
            hashcode = 37 * hashcode + str.charCodeAt(i)
        }

        let index  = hashcode % size //压缩
        return index
    }

    //2、插入和修改
    HashForm.prototype.put = function (key,value) {
        //根据key获取对应的index
        let index = this.hashFunc(key,this.limit)

        //根据index 取出对应的bucket
        let bucket = this.storage[index]

        //判断bucket是否存在
        if (bucket === undefined) {
            bucket = []
            this.storage[index] = bucket
        }

        //判断是否修改数据
        for (let i = 0; i < bucket.length; i++) {
            let 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) {
            let newSize = this.limit * 2
            let newPrime = this.getPrime(newSize) // 容量为质数 是数据分布的更加均匀
            this.resize(newPrime)
        }
    }

    //3、获取操作
    HashForm.prototype.get = function (key) {
        //根据key获取对应的index
        let index = this.hashFunc(key,this.limit)

        //根据index 取出对应的bucket
        let bucket = this.storage[index]
        //判断bucket是否存在
        if (bucket === undefined) { //要获取的值不存在 直接返回null
            return null
        }
        //线性查找
        for (let i = 0; i < bucket.length; i++) {
            let tuple = bucket[i]
            if (key === tuple[0]) {
                return tuple[1]
            }
        }
        return null
    }

    //4、删除操作
    HashForm.prototype.remove = function (key) {
        //根据key获取对应的index
        let index = this.hashFunc(key,this.limit)

        //根据index 取出对应的bucket
        let bucket = this.storage[index]
        //判断bucket是否存在
        if (bucket === undefined) {
            return null
        }

        //线性查找
        for (let i = 0; i < bucket.length;i++) {
            let tuple = bucket[i]
            if (key === tuple[0]) {
                bucket.splice(i,1)
                this.count -= 1
                return tuple[1]

                //缩小容量
                if (this.limit > 7 && this.count < this.limit * 0.25) {
                    let newSize = Math.floor(this.limit / 2)
                    let newPrime = this.getPrime(newSize) // 容量为质数 是数据分布的更加均匀
                    this.resize(newPrime)
                }
            }
        }
        //没有找到 返回null
        return null
    }

    //isEmpty
    HashForm.prototype.isEmpty = function () {
        return this.count === 0
    }

    //获取个数
    HashForm.prototype.size = function () {
        return this.count
    }

    //扩容
    HashForm.prototype.resize = function (newLimit) {

        let oldStorage = this.storage

        this.storage = []
        this.count = 0
        this.limit = newLimit
        //扩容需要将原先所有的数据取出 插入到新扩容到数组中
        for (let i = 0 ; i < oldStorage.length; i++) {

            let bucket = oldStorage[i]

            if (bucket === undefined) {  //为空 没有数据 继续下一个
                continue
            }
            for (let j = 0; j < bucket.length; i++) {
                let tuple = bucket[i]
                this.put(tuple[0],tuple[1])
            }

        }
    }

    //判断质数
    HashForm.prototype.isPrime = function (num) {
        let temp = parseInt(Math.sqrt(num))

        for (let i = 2; i < temp; i++) {
            if (num % i === 0) {
                return false
            }
        }
        return true
    }

    //获取质数
    HashForm.prototype.getPrime = function (num) {
        while (!this.isPrime(num)) {
            num++
        }
        return num
    }
}

const HF = new HashForm()

HF.put('aa','123')
HF.put('bb','189')
HF.put('cc','289')
HF.put('dd','389')

console.log(HF);
console.log(HF.get('aa'));

HF.put('aa','456')
console.log(HF.get('aa'));
console.log(HF.size())

console.log(HF.remove('aa'));
console.log(HF.size())
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值