JavaScript实现哈希表(链地址法)HashTable

使用js实现哈希表, 代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>哈希表, 链地址法</title>
	</head>
	<body>
		<script type="text/javascript">
			//创建哈希表实例
			function HashTable() {
				//初始化
				this.limit = 7
				this.storage = []
				this.count = 0
				//实现哈希函数 hashFun
				HashTable.prototype.hashFun = function(str, size) {
					//设置index
					let index = 0
					//质数: 只能被1或者自己整除
					let hashCode = 37
					for (let i = 0; i < str.length; i++) {
							hashCode = 37 * hashCode + str.charCodeAt(i)
					}
					return index = hashCode % size
				}
				//实现添加/修改操作
				HashTable.prototype.put = function(key, value) {
					let index = this.hashFun(key, this.limit)
					//判断桶是否拥有
					let bucket = this.storage[index]
					//如果有, 则进行判断是否重复
					if(bucket) {
						//如果重复, 则修改
						for(let i = 0; i < bucket.length; i++) {
							let tuple = bucket[i]
							if(tuple[0] === key) {
								tuple[1] = value
								return
							}
						}
							//如果没有, 则添加
						bucket.push([key, value])
						this.count += 1
					}else {
						//如果没有则添加
						bucket = []//初始化数组
						bucket.push([key, value])
						this.count += 1
						this.storage[index] = bucket
					}
					if (this.count > (this.limit * 0.75)) {
						let newlimit = this.limit * 2
						let getprime = this.getprime(newlimit)
						this.resize(getprime)
					}
				}
				//get方法, 用于获取存放的元素
				HashTable.prototype.get = function(key) {
					//根据key获取下标
					let index = this.hashFun(key, this.limit)
					//获取下标所在的源数组
					let bucket = this.storage[index]
					if(bucket) {
						for(let i = 0; i < bucket.length; i++) {
							let tuple = bucket[i]
							if(tuple[0] === key) {
								return tuple
							}
							return undefined
						}
					}else {
						return bucket
					}
				}
				//remove方法, 用于删除元素
				HashTable.prototype.remove = function(key) {
					//根据key获取下标
					let index = this.hashFun(key, this.limit)
					//获取下标所在的源数组
					let bucket = this.storage[index]
					if(bucket) {
						for(let i = 0; i < bucket.length; i++) {
							let tuple = bucket[i]
							if(tuple[0] === key) {
									bucket.splice(i, 1)
									this.limit -= 1
									if(this.count > 7 && this.count < (this.limit * 0.25)) {
										let newlimit = Math.floor(this.limit / 2)
										let getprime = this.getprime(newlimit)
										this.resize(getprime)
									}
									return tuple[1]
							}
							return false
						}
					}else {
						return false
					}
				}
				//isEmpty方法, 用于判断是否为空
				HashTable.prototype.isEmpty = function () {
					return this.count === 0
				}
				//size方法, 返回长度
				HashTable.prototype.size = function() {
					return this.limit
				}
				//resize方法, 扩容数组
				HashTable.prototype.resize = function(newlimit) {
					//先将之前的数组取出
					let oldStorage = this.storage
					//进行扩容操作
					this.storage = []
					this.count = 0
					this.limit = newlimit
					//将之前的内容重新插入
					for(let i = 0; i < oldStorage.length; i++) {
						let bucket = oldStorage[i]
						if(bucket) {
							for(let j = 0; j < bucket.length; j++) {
								let tuple = bucket[j]
								this.put(tuple[0], tuple[1])
							}
						}else {
							continue
						}
					}
				}
				//判断是否是质数, isprime
				HashTable.prototype.isprime = function (num) {
					//判断他的平方根使用sqrt(), 来进行判断
					let tem = parseInt(Math.sqrt(num))
					for(let i = 2; i <= tem; i++) {
						if(num % i === 0) {
							return false
						}
					}
					return true
				}
				//获取质数, getprime
				HashTable.prototype.getprime = function (num) {
					//判断是否是质数, 由于不知道循环的次数, 所以使用while循环
					while (!this.isprime(num)) {
						num++
					}
					return num
				}
			}
			let hash = new HashTable()
			console.log(hash.hashFun('abc', 7))
			console.log(hash.hashFun('cba', 7))
			console.log(hash.hashFun('nba', 7))
			hash.put('abc', 'value')
			hash.put('abc', '修改值')
			hash.put('cba', '插入')
			hash.put('nba', '插入')
			hash.put('aaa', '插入')
			hash.put('bbb', '插入1')
			hash.put('ccc', '插入2')
			hash.put('www', '插入3')
			hash.put('eee', '插入3')
			hash.put('rrr', '插入3')
			hash.put('qqq', '插入3')
			console.log(hash)
			console.log(hash.get('abc'))
			console.log(hash.get('cba'))
			hash.remove('abc')
			console.log(hash)
			console.log(hash.getprime(20))
		</script>
	</body>
</html>

效果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值