zoukankan      html  css  js  c++  java
  • js封装一个哈希表

    // 基于数组封装一个哈希表
    function HashTable() {
        // 属性
        this.storage = [];
        this.count = 0;     // 数据的存储量
        this.limit = 7;     // 容量长度最好为质数,利于数据在容器中均匀分布
        // -----------------方法------------
        // 哈希函数
        HashTable.prototype.hashFunc = function (str,size) {
            // 定义一个hashCode
            let hashCode = 0;
            // 霍纳算法  计算尽可能多加减,少乘除,提高运算效率
            for (var i = 0; i < str.length; i++) {
                hashCode = hashCode * 37 + str.charCodeAt(i)
            }
            // 范围压缩  求余获得位置下标
            let index = hashCode % size;
            return index
        }
        // 新增&修改
        HashTable.prototype.put = function(key,value){
            // 1.通过哈希函数获取到存储位置的下标
            let index = this.hashFunc(key,this.limit);
            // 2.判断这个位置是否有存储内容
            this.storage[index] = this.storage[index] == null ? [] : this.storage[index];
            // 3.判断是修改还是新增
            for(let i = 0;i < this.storage[index].length;i++){
                // 修改
                if(this.storage[index][i][0] === key){
                    this.storage[index][i][1] = value;
                    return
                }
            }
            // 新增
            this.storage[index].push([key,value]);
            // 4.存储数量+1
            this.count++;
            // 5.判断是否需要扩容
            if(this.count > this.limit * 0.75){
                this.resize(this.getPrime(this.limit * 2))
            }
        }
        // 获取
        HashTable.prototype.get = function(key){
            // 1.通过哈希函数获取到位置下标
            let index = this.hashFunc(key,this.limit);
            // 2.判断此位置处是否为空
            let bucket = this.storage[index];
            if(bucket == null) return null;
            // 3.线性查找此位置中存储的数据
            for(let i = 0; i < bucket.length;i++){
                // 找到返回数据
                if(bucket[i][0] === key){
                    return bucket[i][1]
                }
            }
            // 没找到返回null
            return null
        }
        // 删除
        HashTable.prototype.remove = function(key){
            // 1.通过哈希函数获取到index
            let index = this.hashFunc(key,this.limit);
            // 2.判断此位置是否为null
            let bucket = this.storage[index];
            if(bucket == null) return null;
            // 3.遍历找对应的数据
            for(let i = 0; i < bucket.length;i++){
                let tuple = bucket[i];
                // 找到删除此数据
                if(tuple[0] === key){
                    bucket.splice(i,1);
                    // 存储数量-1
                    this.count--;
    
                    // 4.判断是否需要缩容
                    if(this.limit > 7 && this.count < this.limit * 0.25){
                        this.resize(this.getPrime(Math.floor(this.limit / 2)))
                    }
    
                    return tuple[1]
                }
            }
            // 没找到返回null
            return null
        }
        // 哈希表是否为空
        HashTable.prototype.isEmpty = function(){
            return this.count == 0
        }
        // 哈希表中存储元素的个数
        HashTable.prototype.size = function(){
            return this.count
        }
        // 哈希表扩容&缩容
        HashTable.prototype.resize = function(newlimit){
            // 1.用oldStorage承载之前的数据
            let oldStorage = this.storage;
            // 2.重置storage
            this.storage = [];
            this.limit = newlimit;
            this.count = 0;
    
            // 3.遍历 将之前的数据重新存储到新的storage中
            for(var i = 0; i < oldStorage.length; i++){
                let bucket = oldStorage[i];
                if(bucket == null) continue;
                for(var j = 0; j < bucket.length; j++){
                    let tuple = bucket[j];
                    this.put(tuple[0],tuple[1])
                }
            }
        }
    
        // 判断是否是质数
        HashTable.prototype.isPrime = function(num){
            let temp = parseInt(Math.sqrt(num));
            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
        }
    
    }
    
    // 测试
    let hash = new HashTable();
    hash.put('1',{name: 'lili',age:12})
    hash.put('tom',{age:19,id:1234})
    hash.put('mariy',{age:11,sex:'女'})
    console.log(hash);
    // console.log(hash.get('1'));
    // console.log(hash.remove('1'));
    // console.log(hash.get('1'));
    // console.log(hash.isEmpty());
    // console.log(hash.size());
    // hash.put('a',11)
    // hash.put('b',21)
    // hash.put('c',31)
    // hash.put('d',41)
    // hash.put('e',51)
    // console.log(hash);
    // console.log(hash.size());
  • 相关阅读:
    实例15_C语言绘制万年历
    医生酒精
    实例13_求解二维数组的最大元素和最小元素
    用二维数组实现矩阵转置
    C语言中的typedef跟define的区别
    C语言设计ATM存取款界面
    MyBatis,动态传入表名,字段名的解决办法
    在mybatis执行SQL语句之前进行拦击处理
    使用Eclipse构建Maven的SpringMVC项目
    Debug过程中的mock (及display窗口的使用)
  • 原文地址:https://www.cnblogs.com/cyf666cool/p/14837210.html
Copyright © 2011-2022 走看看