数据结构之散列表(Hash Table)

版权声明: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43154931/article/details/82822029