哈希表实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>哈希表实现</title>
</head>
<body>
    
    <script>
        // 封装哈希表类
        function HashTable(){
            // 属性
            this.storage = []
            this.count = 0
            this.limit = 7  
             
            // 方法
            // 哈希函数
            HashTable.prototype.hashFunc = function(str,size){
                // 定义变量
                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 是否为空
                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.resie(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 进行 线性查找
                for(var i =0;i<bucket.length;i++){
                    var tupple = bucket[i]
                    if(tupple[0] == key){
                        return tupple[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 是否为空
                if(bucket == null){
                    return null
                } 
                // 4 进行 线性查找
                for(var i =0;i<bucket.length;i++){
                    var tupple = bucket[i]
                    if(tupple[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 tupple[1]
                    }
                } 

                // 5  没有找到 返回null
                return null
            }

            // 其它方法

            // 判断哈希表是否为 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 取出对应的 buccket
                    var bucket = oldStorage[i]
                    // 3.2 判断 bucket 是否为null
                    if(bucket == null){
                        continue
                    }
                    // 3.3 bucket 中有数据, 取出数据,重新插入
                    for(var j=0; j<bucket.length;i++){
                        var tuple = bucket[j]
                        this.put(tuple[0],tuple[1])
                    }
                }



            }

            // 判断传入的数字是否是质数 
            // 特点 只能被1和自己整除, 不能被 2 到 num -1 之间的数整除
            HashTable.prototype.isPrime= function(num){ 
                // 1 获取 num的 平方根
                var temp = parseInt(Math.sqrt(num)) 
                // 2 循环判断
                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
            }
        }

        // 测试哈希表

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

        // 2 插入数据
        ht.put('abc','123')
        ht.put('cba','321')
        ht.put('nba','521')
        ht.put('mba','520')

        // 3 获取数据
        console.log(ht.get('abc'))

        // 4 修改方法                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
        ht.put('abc','111')
        console.log(ht.get('abc'))


        alert(ht.list())

        // 5 删除方法
        ht.remove('abc')
        console.log(ht.get('abc'))
    </script>
</body>
</html>
posted @ 2021-01-15 15:22  13522679763-任国强  阅读(95)  评论(0)    收藏  举报