<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//设计哈希函数
// 1>将字符串转化为较大的数字HashCode
// 2>将较大数字压缩到数组
function hashFunc(str, size) {
// 1.定义变量
var hashCode = 0;
// 2.霍纳法则
for (var i = 0; i < str.length; i++) {
hashCode = 37 * hashCode + str.charCodeAt(i);
}
//取余操作
var index = hashCode % size;
return index
}
//测试
console.log(hashFunc('abc', 7))
//哈希表
function HashTable() {
//属性
this.storage = [] //数组
this.count = 0 //存放数的个数
this.limit = 7 //数组长度
//方法
HashTable.prototype.hashFunc = function(str, size) {
// 1.定义变量
var hashCode = 0;
// 2.霍纳法则
for (var i = 0; i < str.length; i++) {
hashCode = 37 * hashCode + str.charCodeAt(i);
}
//取余操作
var index = hashCode % size;
return index
}
//插入/修改
HashTable.prototype.put = function(key, value) {
//获取key对应index
var index = this.hashFunc(key, this.limit)
//判断bucket是否为空
var bucket = this.storage[index];
//判断bucket是否为龙
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 true
}
}
bucket.push([key, value])
this.count++
//判断是否需要扩容
if (this.count > this.limit * 0.75) {
this.resize(this.limit * 2)
}
}
//获取
HashTable.prototype.get = function(key) {
//更根据key获取对应的index
var index = this.hashFunc(key, this.limit)
//更具index获取对应的bucket
var bucket = this.storage[index]
//判断bucket是否为空
if (bucket == null) {
return null
}
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i]
if (tuple[0] = bucket[i]) {
return tuple[1]
}
}
}
HashTable.prototype.remove = function(key) {
//更根据key获取对应的index
var index = this.hashFunc(key, this.limit)
//更具index获取对应的bucket
var bucket = this.storage[index]
//判断bucket是否为空
if (bucket == null) {
return null
}
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i]
if (tuple[0] = bucket[i]) {
bucket.splice(i, 1)
this.count--
return tuple[1]
if (this.limit > 7 && this.count < this.limit * 0.25) {
this.resize(Math.floor(this.limit / 2))
}
}
}
return null
}
HashTable.prototype.isEmpty = function() {
return this.count == 0
}
HashTable.prototype.size = function() {
return this.count
}
//哈希表的扩容
HashTable.prototype.resize = function() {
var oldstorage = this.storage
//重置所有属性
//属性
this.storage = [] //数组
this.count = 0 //存放数的个数
this.limit = newLimite //数组长度
for (var i = 0; i < oldstorage.length; i++) {
var bucket = oldstorage[i]
//3.2判断bucket是否为空
if (bucket == null) {
continue
}
// 3.3bucket中有数据,那么取出数据,重新插入
for (var j = 0; j < bucket.length; j++) {
var tuple = bucket[j]
this.put(tuple[0], tuple[1])
}
}
}
}
//测试
var ht = new HashTable()
//插入
ht.put('acs', '123')
ht.put('cba', '321')
ht.put('nba', '521')
ht.put('mba', '520')
console.log(ht)
//据哦去
ht.put("acs", '111')
console.log(ht.get('acs'))
//删除
ht.remove("acs")
console.log(ht.get('acs'))
</script>
</body>
</html>