优秀的哈希函数:
哈希表的优势在于它的速度,所以哈希函数不能采用消耗性能较高的复杂算法。提高速度的一个方法是在哈希函数中尽量减少乘法和除法。
性能高的哈希函数应具备以下两个优点:
- 快速的计算;
- 均匀的分布;
霍纳法则:在中国霍纳法则也叫做秦久韶算法,具体算法为:
求多项式的值时,首先计算最内层括号内一次多项式的值,然后由内向外逐层计算一次多项式的值。这种算法把求n次多项式f(x)的值就转化为求n个一次多项式的值。
初步封装哈希表
哈希表的常见操作为:
- put(key,value):插入或修改操作;
- get(key):获取哈希表中特定位置的元素;
- remove(key):删除哈希表中特定位置的元素;
- isEmpty():如果哈希表中不包含任何元素,返回trun,如果哈希表长度大于0则返回false;
- size():返回哈希表包含的元素个数;
- resize(value):对哈希表进行扩容操作;
哈希函数的简单实现:
首先使用霍纳法则计算hashCode的值,通过取余操作实现哈希化,此处先简单地指定数组的大小
//设计哈希函数
//1.将字符串 转成比较大的数字:hashCode
//2.将大的数字hashCode压缩到数组范围(大小)之内
function hashFun(str, size) {
// 1.定义hashCode变量
let hashCode = 0
//2.霍纳算法,来计算我门hashCode的值
for (let i = 0; i < str.length; i++) {
hashCode = 37 * hashCode + str.charCodeAt(i)
}
//取余操作
let index = hashCode % size
return index
}
alert(hashFun('abc', 7))
alert(hashFun('cba', 7))
alert(hashFun('nba', 7))
alert(hashFun('maa', 7))
put(key,value):插入或修改操作;
// 插入和修改方法
Hash.prototype.put = function (key, value) {
//1.根据key获取对应的index
let index = this.hashFun(key, this.limit)
//2.根据index取出对应的bucket
let bucket = this.storage[index]
//3.判断该bucket是否为null
if (bucket == null) {
bucket = []
}
// 判断是否修改数据
for (let i = 0; i < bucket.length; i++) {
let tuple = bucket[i]
if (tuple[0] == key) {
tuple[1] = value
return
}
}
// 5.进行添加操作
bucket.push([key, value])
this.count += 1
}
get(key):获取哈希表中特定位置的元素;
//获取操作
Hash.prototype.gey = function (key) {
//1.根据key获取对应的index
let index = this.hashFun(key, this.limit)
// 2.根据index获取对应的bucket
let bucket = this.storage[index]
//3.判断该bucket是否为null
if (bucket == null) {
return null
}
//4.有bucket,那么就斤西瓜线性查找
for (let i = 0; i < bucket.length; i++) {
let tuple = bucket[i]
if (tuple[0] == key) {
return tuple[1]
}
}