版权声明:Oreo https://blog.csdn.net/weixin_43154931/article/details/82822029
JavaScript实现散列表(hash map/ hash table)
- 散列表数据结构
- hash table 代码
- 改进后hash table 代码
- hash算法改进
1. 双向链表数据结构
散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。(wiki百科)
2. hash table 代码
const HashTable = function() {
// 散列表
let tables = [];
this.put = function(key, value) {
// 向散列表增加一个新的项
let position = loseloseHashCode(key);
console.log(position + '--' + key);
tables[position] = value;
}
this.remove = function(key) {
// delete value accroding to key
tables[loseloseHashCode(key)] = undefined;
}
this.get = function(key) {
// return value according to key
return tables[loseloseHashCode(key)];
}
const loseloseHashCode = function(key) {
// 通过固定的算法, 将key转换成散列值
let hash = 0;
for (let i = 0; i < key.length; i++) {
hash += key.charCodeAt(i);
}
return hash % 37;
};
}
缺点: 如果key 重复,新值会覆盖旧值
3 hash table 代码改进
此处引用了LinkedList类
const HashMap = function() {
// 散列表2, 解决HashTable冲突问题(分离链接)
let tables = [];
this.put = function(key, value) {
// 向散列表增加一个新的项
let position = loseloseHashCode(key);
if (tables[position] == undefined) {
tables[position] = new LinkedList();
}
tables[position].append(new ValuePair(key, value));
}
this.remove = function(key) {
// delete value accroding to key
let position = tables[loseloseHashCode(key)];
if (tables[position] !== undefined) {
let current = tables[position].getHead();
while (current.next) {
if (current.element.key === key) {
tables[position].remove(current.element);
if (tables[position].isEmpty()) {
tables[position] = undefined;
}
return true;
}
current = current.next;
}
// 检查是否为第一个或者最后一个元素
if (current.element.key === key) {
tables[position].remove(current.element);
if (tables[position].isEmpty()) {
tables[position] = undefined;
}
return true;
}
}
return false;
}
this.get = function(key) {
// return value according to key
let position = loseloseHashCode(key);
if (tables[position] !== undefined) {
let current = tables[position].getHead();
while (current.next) {
if (current.element.key === key) {
return current.element.value;
}
current = current.element;
}
// 检查元素第一个或者最后一个节点的情况
if (current.element.key === key) {
return current.element.value;
}
}
return undefined;
}
const loseloseHashCode = function(key) {
// 通过固定的算法, 将key转换成散列值
let hash = 0;
for (let i = 0; i < key.length; i++) {
hash += key.charCodeAt(i);
}
return hash % 37;
};
const ValuePair = function(key, value) {
this.key = key;
this.value = value;
this.toString = function() {
return '[' + this.key + ' - ' + this.value + ']';
}
}
}
3 hash算法改进
loseloseHashCode并不是一个很好的散列函数,很容易造成重复。
const newHashCode = function(key) {
let hash = 5381;
for ( let i = 0; i < key.length; i++) {
hash = hash * 33 + key.charCodeAt(i);
}
return hash % 1013;
}