<!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>
// 封装哈希表类
function HashTable() {
// 属性
this.storage = [] //存储数据
this.count = 0 //数组当前长度
this.limit = 7 //数组最大长度
// 方法
// 哈希函数
HashTable.prototype.hashFunc = function (str, size) {
// 1.将字符串转成比较大的数字: hashCode
// 2.将大的数字hashCode压缩到数组范围(大小)之内
// 1.定义hashCode变量
var hashCode = 0
// 2.霍纳算法,来计算hashCode的值
for (var i = 0; i < str.length; i++) {
hashCode = 37 * hashCode + str.charCodeAt(i)
}
// 3.取余操作
var index = hashCode % size
return index
}
// 插入/修改数据
HashTable.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
// 6.判断是否需要扩容操作
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) {
// 1.根据key获取对应的index
var index = this.hashFunc(key, this.limit)
// 2.根据index获取对应的bucket
var bucket = this.storage[index]
// 3.判断bucket是否为空
if (bucket == null) {
return null
}
// 4.有bucket,那么就进行线性查找
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i]
if (tuple[0] == key) {
return tuple[1]
}
}
// 5.依然没有找到
return null
}
// 删除操作
HashTable.prototype.remove = function (key) {
// 1.根据key获取对应的index
var index = this.hashFunc(key, this.limit)
// 2.根据index获取对应的bucket
var bucket = this.storage[index]
// 3.判断bucket是否为空
if (bucket == null) {
return null
}
// 4.有bucket,那么就进行线性查找,并且删除
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]
}
}
// 5.依然没有找到
return null
}
// 其他方法
// 判断哈希表是否为空
HashTable.prototype.isEmpty = function () {
return this.count == 0
}
// 获取哈希表中元素的个数
HashTable.prototype.size = function () {
return this.count
}
// 哈希表扩容/缩容
HashTable.prototype.resize = function (newLimit) {
// 1.保存旧的数组内容
var oldStorage = this.storage
// 2.重置所有的属性
this.storage = []
this.count = 0
this.limit = newLimit
// 3.遍历oldStorage中所有的bucket
for (var i = 0; i < oldStorage.length; i++) {
// 3.1取出对应的bucket
var bucket = oldStorage[i]
// 3.2判断bucket是否为null
if (bucket == null) {
continue
}
// 3.3bucket中有数据,那么就取出数据,重新插入
for (var j = 0; j < bucket.length; j++) {
var tuple = bucket[j]
this.put(tuple[0], tuple[1])
}
}
}
// 判断某个数字是否是质数
HashTable.prototype.isPrime = function (num) {
// 1.获取num的平方根
var temp = parseInt(Math.sqrt(num))
// 2.循环判断
for (var i = 0; i < temp; i++) {
if (num % i == 0) {
return false
}
}
return true
}
// 获取质数的方法
HashTable.prototype.getPrime = function (num) {
// 14->17
// 34->37
while (!this.isPrime(num)) {
num++
}
// 当num为质数时终止循环
return num
}
}
// 测试哈希表
// 1.创建哈希表
var ht = new HashTable()
// 2.插入数据
ht.put('a', '123')
ht.put('b', '321')
ht.put('c', '525')
ht.put('d', '520')
// 3.获取数据
alert(ht.get('a'))
// 4.修改方法
ht.put('a', '111')
alert(ht.get('a'))
// 5.删除方法
ht.remove('a')
alert(ht.get('a'))
// 6.判断哈希表是否为空
alert(ht.isEmpty())
// 7.获取哈希表元素个数l
alert(ht.size())
</script>
</body>
</html>
JavaScript 数据结构-哈希表
最新推荐文章于 2022-08-14 20:56:01 发布