JavaScript 数据结构-哈希表

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 封装哈希表类
        function HashTable() {
            // 属性
            this.storage = [] //存储数据
            this.count = 0 //数组当前长度
            this.limit = 7 //数组最大长度

            // 方法
            // 哈希函数
            HashTable.prototype.hashFunc = function (str, size) {
                // 1.将字符串转成比较大的数字: hashCode
                // 2.将大的数字hashCode压缩到数组范围(大小)之内

                // 1.定义hashCode变量
                var hashCode = 0

                // 2.霍纳算法,来计算hashCode的值
                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 += 1

                // 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是否为空
                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.依然没有找到
                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是否为空
                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 = Math.floor(this.limit / 2)
                            var newPrime = this.getPrime(newSize)
                            this.resize(newPrime)
                        }
                        return tuple[1]
                    }
                }

                // 5.依然没有找到
                return null
            }

            // 其他方法
            // 判断哈希表是否为空
            HashTable.prototype.isEmpty = function () {
                return this.count == 0
            }

            // 获取哈希表中元素的个数
            HashTable.prototype.size = function () {
                return this.count
            }

            // 哈希表扩容/缩容
            HashTable.prototype.resize = function (newLimit) {
                // 1.保存旧的数组内容
                var oldStorage = this.storage

                // 2.重置所有的属性
                this.storage = []
                this.count = 0
                this.limit = newLimit

                // 3.遍历oldStorage中所有的bucket
                for (var i = 0; i < oldStorage.length; i++) {
                    // 3.1取出对应的bucket
                    var bucket = oldStorage[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) {
                // 1.获取num的平方根
                var temp = parseInt(Math.sqrt(num))

                // 2.循环判断
                for (var i = 0; i < temp; i++) {
                    if (num % i == 0) {
                        return false
                    }
                }
                return true
            }

            // 获取质数的方法
            HashTable.prototype.getPrime = function (num) {
                // 14->17
                // 34->37
                while (!this.isPrime(num)) {
                    num++
                }
                // 当num为质数时终止循环
                return num
            }
        }

        //   测试哈希表
        // 1.创建哈希表
        var ht = new HashTable()

        // 2.插入数据
        ht.put('a', '123')
        ht.put('b', '321')
        ht.put('c', '525')
        ht.put('d', '520')

        // 3.获取数据
        alert(ht.get('a'))

        // 4.修改方法
        ht.put('a', '111')
        alert(ht.get('a'))

        // 5.删除方法
        ht.remove('a')
        alert(ht.get('a'))

        // 6.判断哈希表是否为空
        alert(ht.isEmpty())

        // 7.获取哈希表元素个数l
        alert(ht.size())
    </script>
</body>

</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值