搜索
您的当前位置:首页正文

javascript数据结构与算法----哈希表扩容

来源:好走旅游网
HashTable.prototype.resize=function(newlimit){
    // 先保存就得数据
    var oldStorage = this.storage
    // 重置属性
    this.storage = []
    this.count = 0
    this.limit = newlimit

    // 遍历
    for(var i =0;i<oldStorage.length;i++){
        var bucket = oldStorage[i]
        if(!bucket){
            continue
        }else{
            for(var j=0;j<bucket.length;j++){
                var tuple = bucket[i]
                this.put(tuple[0],tuple[1])
            }
        }
    }
}

在元素进行插入的时候,需要进行判断是否需要进行扩容操作

if(this.count >  this.limit * 0.75){
    this.resize(this.limit * 2)
}


// 优化原本的put的实现
    HashTable.prototype.put=function(key,value){
       // 1.根据key获取index
       var index = this.hashFunc(key,this.limit)

       // 根据index取出对应的桶
       var bucket = this.storage[index]
       // 如果对应的位置没有桶那么就进行新创建
       if(!bucket){
         bucket = []
         this.storage[index] = bucket
       }
       // 判断是否是修改数据
       for(var i=0;i<bucket.length;i++){
         var tuple = bucket[i]  //此时bucket的每一个元素也是数组的形式
         if(tuple[0] == key){
           tuple[1] = value
           return 
         }
       }

       // 进行添加
       bucket.push([key,value])
       this.count += 1

       if(this.count >  this.limit * 0.75){
           this.resize(this.limit * 2)
       }
     }

(4)哈希表缩容,在删除操作的时候,

if(this.limit >7 && this.count < this.limit * 0.25 ){
    this.resize(Math.floor(this.limit/2))
}

优化原本的删除操作

HashTable.prototype.remove=function(key){
    var index = this.hashFunc(key,this.limit)
    var bucket = this.storage[index]
    if(!bucket){
        return null
    }else{
        for(var i=0;i<bucket.length;i++){
            var tuple = bucket[i]
            if(tuple[0] == key){
                // 从bucket数组中删除当前元素i
                bucket.splice(i,1)
                // 总数减少
                this.count--
                // 缩容
                if(this.limit >7 && this.count < this.limit * 0.25 ){
                    this.resize(Math.floor(this.limit/2))
                }
                // 返回当前删除的元素
                return tuple[1]
            }
        }
        return null
    }
}

对扩容进行优化,判断扩容之后是不是一个质数,如果不是质数的话,就需要寻找一个接近于2 被的质数,将这个新的质数作为新的容量。
面试题:如何判断一个数是不是质数?
第一种实现:通过循环,但是效率不是很高。

 function judeNum(num){
   if(typeof num != 'number'){
     return '请输入一个数字'
   }else{
     // 循环输出
     for(var i=2;i<num;i++){
       if(num % i == 0) return `${num}不是质数`
     }
     return `${num}是质数`
   }
 }

第二种实现:
如果一个数字能够被分解,那么它分解的因子一个会大于等于它本身的开平方根,一个小于等于它本身的开平方根。

function judeNum2(num){
  if(typeof num != 'number'){
    return '请输入一个数字'
  }else{
    var temp = parseInt(Math.sqrt(num))
    for(var i=2;i<=temp;i++){
      if(num % i == 0) return `${num}不是质数`
    }
    return `${num}是质数`
  }
}

如何岁哈希表的扩容进行优化?

  // 判断当前传入数字是否是质数
  HashTable.prototype.isPrime=function(num){
    var 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
  }

getPrime函数的调用是在改变数组容量的地方,即是元素添加和操作删除的地方,优化原本的代码为

if(this.count > this.limit * 0.75){
  var newSize = this.getPrime(this.limit * 2)
  this.resize(newSize)
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Top