(js描述的)数据结构[哈希表1.3](10)

1.哈希表的完善

1.容量质数(limit):需要恒为质数,来确保元素的均匀分布。
1)普通算法: 判断一个数是否为质数

	function isPrime(num) {
		 for (var i = 2; i < num; i++) {
		 if (num % i == 0) {
		 	return false
		 }
	} return true
	}
  1. 升级算法:只需要判断到(sqrt(num))就可以
	function isPrime(num) {
		var temp = parseInt(Math.sqrt(num)) 
		for (var i = 0; i <= num; i++) {
			if (num % i == 0) {
		 	return false
		 }
		}return true
	} 

--------------------------实现恒容量恒质数的哈希表---------------------------------
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

// 封装哈希表
         function HashMap() {
             //属性
             this.storage = []  //存储数据
             this.count = 0     //插入元素数量
             this.limit = 7     //数组容量

            //方法
            //哈希函数
            HashMap.prototype.hashFunc =  function (str, size) {
                //定义hashCode
                var hashCode = 0
                for (var i =0; i < str.length ; i++) {
                    hashCode = 37*hashCode + str.charCodeAt(i)
                }
                var index = hashCode % size
                return index
            }

            // 插入&修改
            HashMap.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

                //扩容
                if (this.count > this.limit * 0.75) {
                    var newLimit = this.getPrime(this.limit * 2)
                    this.resize(newLimit)
                }
            }

            //获取操作
            HashMap.prototype.get =function(key) {
                // 1.根据key获取对应的index
                var index = this.hashFunc(key, this.limit)
                // 2.根据index取出对应的bucket
                var bucket = this.storage[index]
                // 3.判断bucket是否为null
                if (bucket == null) {
                    return null
                }
                // 4.判断是否存在数据
                for (var i = 0; i< bucket.length; i++) {
                    var tuple = bucket[i]
                    if (tuple[0] == key) {
                        return tuple[1]
                    }
                }
                return null
            } 
            //删除操作
            HashMap.prototype.remove =function(key) {
                // 1.根据key获取对应的index
                var index = this.hashFunc(key, this.limit)
                // 2.根据index取出对应的bucket
                var bucket = this.storage[index]
                // 3.判断bucket是否为null
                if (bucket == null) {
                    return null
                }
                // 4.判断是否存在数据
                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 newLimit = this.getPrime(Math.floor(this.limit / 2))
                            this.resize(newLimit)
                        }
                        return tuple[1]
                    }
                }
                return null
            } 
            // 其他方法
            //isEmpty方法
            HashMap.prototype.isEmpty = function() {
                return this.count == 0
            }
            //size方法
            HashMap.prototype.size = function() {
                return this.count
            }

            //数组扩容或缩容
            HashMap.prototype.resize = function(newLimit) {
                //保存所有属性
                var oldStorage = this.storage
                //重置所有属性
                this.count = 0
                this.limit = newLimit
                this.storage = []
                //遍历oldStorage中所有的bucket
                for (var i = 0; i < oldStorage.length; i++) {
                    var bucket = oldStorage[i]
                    if (bucket == null) {
                        continue
                    }
                    for (var j = 0; i< bucket.length; j++) {
                        var tuple = bucket[j]
                        this.put(tuple[0], tuple[1])
                    }
                }
            }
            //判断是否是质数
            HashMap.prototype.isPrime = function(num) {
		        var temp = parseInt(Math.sqrt(num)) 
		        for (var i = 0; i <= num; i++) {
		        	if (num % i == 0) {
		         	return false
		         }
		        }return true
            } 
            //获取质数
            HashMap.prototype.getPrime = function(num) {
                while (!this.isPrime(num)) {
                    num++
                }
                return num
            }
        }
posted @ 2020-04-05 12:10  jacksonni  阅读(144)  评论(0编辑  收藏  举报