数据结构day3-3 哈希表

 

 

 

    function HashTable() {
      this.storage = []
      this.count = 0
      this.limit = 7

      // 哈希函数
      HashTable.prototype.hashFunc = function (str,size) {
        var hashCode = 0

        for(var i=0; i<str.length; i++) {
          hashCode = 37 * hashCode + str.charCodeAt(i)
          
        }
        index = hashCode % size

        return index
      }

      // 插入修改操作
      HashTable.prototype.put = function(key,value) {
        // 根据key获取索引值 将数据插入到对应的位置
        // 根据索引值 取出bucket(桶)
        // 如果桶不存在创建桶 放置在该索引的位置
        // 判断是新增还是修改原来的值
        var index = this.hashFunc(key,this.limit)
        var bucket = this.storage[index]
        if(bucket == null) {
          bucket = []
          this.storage[index] = bucket
        }
        // 判断是否是修改
        for (var i=0; i< bucket.length; i++) {
          var 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) {
          var newSize = this.limit * 2
          var newPrime = this.getPrime(newSize)
          this.resize(newPrime)
        }
      }
      HashTable.prototype.get = function(key) {
        //根据key获取对应的index 根据index 获取对应的bucket
        //判断bucket如果为null直接返回null
        //线性的查找bucket中每一个key是否等于传入的key
        var index = this.hashFunc(key,this.limit)
        var bucket = this.storage[index]
        if(bucket == null) {
          return null
        }
        // 有值 线性查找
        for (var i=0; i< bucket.length; i++) {
          var tuple = bucket[i]
          if (tuple[0] == key) { 
            return tuple[1]
          }
        }

        return null
      }

      HashTable.prototype.remove = function(key) {
        //根据key获取对应的index 根据index 获取对应的bucket
        //判断bucket如果不存在直接返回null
        //线性的查找bucket中每一个key是否等于传入的key 并且删除
        var index = this.hashFunc(key,this.limit)
        var bucket = this.storage[index]
        if(bucket == null) {
          return null
        }
        // 有值 线性查找 删除
        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]
        }

        return null
      }
      //判断哈希表是否为空
      HashTable.prototype.isEmpty = function() {
        return this.count == 0
      }
      //获取哈希表元素个数
      HashTable.prototype.size = function() {
        return this.count
      }

      HashTable.prototype.resize = function(newLimit) {
        // 保存旧的数组内容
        var oldStorage = this.storage
        //
        this.storage = []
        this.count = 0
        this.limit = newLimit
        // 遍历oldStorage中所有bucket
        for(var i=0; i<oldStorage.length; i++) {
          var bucket = oldStorage[i]
          if (bucket == null) {
            continue
          }
          for(var j=0; j<bucket.length; j++) {
            var tuple = bucket[j]
            this.put(tuple[0],tuple[1]) //key,value重新插入新的数组
          }
        }
      }
      // 判断是否为质数
      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
      }
    }

    var ht = new HashTable()

    ht.put('abc','123')
    ht.put('cba','321')
    ht.put('nba','521')

    alert(ht.get('abc'))

    ht.put('abc','111')
    alert(ht.get('abc'))

    ht.remove('abc')
    alert(ht.get('abc'))

 

posted @ 2019-07-12 17:38  suanmei  阅读(158)  评论(0编辑  收藏  举报