JavaScript数据结构——散列表(Hash table,也叫哈希表)
概念和结构
- 散列表是根据关键码值(Key value)而直接进行访问的数据结构。
- 若关键字为
k
,则其值存放在f(k)
的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f
为散列函数,按这个思想建立的表为散列表。
哈希表的操作
哈希表有三种常用操作,分别为
- 添加元素
put(key, value)
- 通过键移除元素
remove(key)
- 由键获取值
get(key)
JS实现
JS里面的哈希表结构需要通过数组(array)来实现,因为JS中只有数组才有快速定位的能力。
var HashTable = function(){var hashTable = [];//定义散列函数loseloseHashCodefunction loseloseHashCode(key){var hashcode = 0;for(var i = 0; i < key.length; i++){hashcode += key[i].charCodeAt();}return hashcode % 37;}//添加元素this.put = function(key , value){hashTable[loseloseHashCode(key)] = value;}//移除元素this.remove = function(key){hashTable[loseloseHashCode(key)] = undefined;}//获取元素值this.get = function(key){return hashTable[loseloseHashCode(key)];}}
哈希冲突
不同关键字的哈希函数值可能相同,这种现象称之为哈希冲突。
有两种解决方法:
- 分离链接法
- 线性探查法
分离链接法
分离链接法就是将散列值相同的所有元素保留到同一个链表中。
分离链接法的JS实现
因为要将哈希函数值相同的所有元素都保存到一个链表中,因此我们需要用到链表这个类。这个类在之前我们已经实现过了,如果有不清楚的同学可以前往JavaScript数据结构——链表(Linked List)。
var HashTable = function(){//定义辅助类var Node = function(key , value){this.key = key;this.value = value;}var hashTable = [];//定义散列函数function loseloseHashCode(key){var hashcode = 0;for(var i = 0; i < key.length; i++){hashcode += key[i].charCodeAt();}return hashcode % 37;}//添加元素this.put = function(key , value){var position = loseloseHashCode(key);if(hashTable[position]){//哈希表的位置存在元素hashTable[position].append(new Node(key , value));}else{//那个位置没有元素hashTable[position] = new LinkedList();hashTable[position].append(new Node(key , value));}}//获取元素值this.get = function(key){var position = loseloseHashCode(key);if(hashTable[position]){var current = hashTable[position].getHead();while(current){if(current.element.key === key){return current.element.value;}else{current = current.next;}}return undefined;}else{return undefined;}}//移除元素this.remove = function(key){var position = loseloseHashCode(key);if(hashTable[position]){var current = hashTable[position].getHead();//找到key所在的链表节点currentwhile(current){if(current.element.key === key){hashTable[position].remove(current.element);//移除后如果链表为空,则设为undefinedif(hashTable[position].isEmpty()){hashTable[position] = undefined;}return true;}else{current = current.next;}}return false; }else{return false;}}
}//链表生成函数
function LinkedList(){var head = null;var length = 0;//定义辅助类,用来生成节点var Node = function(element){this.element = element;this.next = null;}//向链表尾部添加元素this.append = function(element){//根据传进来的element构建链表节点var node = new Node(element);if(head === null){//如果是空链表就直接设为链表头head = node;}else{//不然将最后一个节点的next属性指向它var lastNode = head;while(lastNode.next !== null){lastNode = lastNode.next;}lastNode.next = node;}length ++;}//插入元素this.insert = function(position,element){//解决越界if(position > -1 && position < length){var node = new Node(element);if(position === 0){var oldHead = head;head = node;node.next = oldHead;}else{var preNode = null;var currentNode = head;index = 0;while(index !== position){preNode = currentNode;currentNode = currentNode.next;index ++;}preNode.next = node;node.next = currentNode;}length ++;}}//移除指定位置元素this.removeAt = function(position){//解决越界if(position > -1 && position < length){if(position === 0){var currentNode = head;head = currentNode.next;}else{var preNode = null;var currentNode = head;index = 0;while(index !== position){preNode = currentNode;currentNode = currentNode.next;index ++;}preNode.next = currentNode.next;}length --;return currentNode;}}//获取元素索引this.indexOf = function(element){var index = 0;var currentNode = head;while(currentNode){if(currentNode.element === element){return index;}currentNode = currentNode.next;index ++;}return -1;}//移除指定元素this.remove = function(element){//复用return this.removeAt(this.indexOf(element));}//检查链表是否为空this.isEmpty = function(){return length === 0;}//获取链表长度this.size = function(){return length;}//获取链表头this.getHead = function(){return head;}
}
线性探查法
线性探查法就是如果位置被占用线性向下移动。比如哈希函数值为N
的位置被占用了,而N+1
为空,那么就将这个元素放置在N+1
的位置上,如果N+1
的位置上也被占用了,则继续向下线性查找。
线性探查法的JS实现
因为在找到某个key
的对应位置后,可能这个位置存放的不是我们想要的那个value
,因此在存放的时候应该把key
也一起存放进去,而不单单只存放一个value
,好方便进行比较。
function HashTable(){//定义辅助类var Node = function(key , value){this.key = key;this.value = value;}//定义散列函数function loseloseHashCode(key){var hashcode = 0;for(var i = 0; i < key.length; i++){hashcode += key[i].charCodeAt();}return hashcode % 37;}var hashTable = [];//添加元素this.put = function(key , value){var position = loseloseHashCode(key);if(hashTable[position]){//哈希表的位置存在元素while(hashTable[position]){position ++;}hashTable[position] = new Node(key , value);}else{//那个位置没有元素hashTable[position] = new Node(key , value);}}//获取元素值this.get = function(key){var position = loseloseHashCode(key);if(hashTable[position]){//那个位置有元素while(hashTable[position]){if(hashTable[position].key === key){return hashTable[position].value;}else{position ++;}}return undefined;}else{//那个位置没有元素return undefined;}}//移除元素this.remove = function(key){var position = loseloseHashCode(key);if(hashTable[position]){while(hashTable[position]){if(hashTable[position].key === key){hashTable[position] = undefined;return true;}else{position ++;}}return false;}else{return false;}}
}
更好的散列函数
好的散列函数能让冲突率下降,减少冲突的发生。
var djb2HashCode = function(key){var hashCode = 5381;for(var i = 0; i < key.length; i++){hashCode = hashCode * 33 + key.charCodeAt(i);}return hashCode % 1013;
}
JavaScript数据结构——散列表(Hash table,也叫哈希表)相关推荐
- 数据结构--散列表 Hash Table
文章目录 1.线性探测 哈希表代码 2.拉链法 哈希表代码 1. 散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来.可以说,如果没有数组,就没有散列表. ...
- 散列表(Hash Table)
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列 ...
- 什么是散列表(Hash Table)
散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度 ...
- 白话算法(6) 散列表(Hash Table)从理论到实用(中)
不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好的)方法.推动科技进步的人,永远是那些敢于问出比外行更天真.更外行的问题, ...
- JavaScript 数据结构与算法(二)哈希表
本文参考文献:https://www.cnblogs.com/AhuntSun-blog/p/12636718.html 配套视频教程:https://www.bilibili.com/video/B ...
- 白话算法(6) 散列表(Hash Table) 从理论到实用(下)
[澈丹,我想要个钻戒.][小北,等等吧,等我再修行两年,你把我烧了,舍利子比钻戒值钱.] --自扯自蛋 无论开发一个程序还是谈一场恋爱,都差不多要经历这么4个阶段: 1)从零开始.没有束缚的轻松感.似 ...
- Redis散列表(hash)使用
Redis有5种常用的数据结构,分别为:string(字符串),list(列表),hash(哈希表或散列表),set(集合)和zset(有序集合).5种数据结构指的是作为键值对的值存在于Redis库中 ...
- ds哈希查找—二次探测再散列_大白话之哈希表和哈希算法
哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...
- 10_JavaScript数据结构与算法(十)哈希表
JavaScript 数据结构与算法(十)哈希表 认识哈希表 哈希表是一种非常重要的数据结构,几乎所有的编程语言都直接或者间接应用这种数据结构. 哈希表通常是基于数组实现的,但是相对于数组,它存在更多 ...
最新文章
- Kafka核心设计与实践原理总结:基础篇
- 在Linux(Ubuntu)下搭建ASP.NET Core环境并运行 继续跨平台
- 电信/移动/联通同台秀肌肉 集体表态:云计算市场“不能丢”!
- 永不示弱_永不过时的网页设计:今天和2000年的在线投资组合
- 数据结构(Java)-哈希表
- 让Linux使用malloc申请更多的内存
- kibana常见启动报错
- python读取字符串按列分配后按行读出
- 每日学习笔记(13)
- zblog mysql修改_MySQL_网上下载的Zblog模板怎么修改?, 终于下 - phpStudy
- 如何在海量元素中(例如 10 亿无序、不定长、不重复)快速判断一个元素是否存在?
- Rebase Current onto Selected
- ImageNet数据集的0到999Label对应的类别分别是什么
- ctypes调用海康威视人脸抓拍机并将抓拍的人脸上传到指定地址
- C Runtime Library 与 STL
- 斐波那契序列递归方法_斐波那契和卢卡斯序列
- Codeforces-715B-Complete The Graph(最短路)
- 【CSS 形状 (Shapes)】
- mPEG-OPSS MPEG-SPDP 甲氧基PEG巯基吡啶
- java计算机毕业设计智能推荐电影网站源码+mysql数据库+系统+lw文档+部署
热门文章
- vue-select-lang
- 面试题:String StringBufere StringBuilder 不用看
- CSRF 攻击的应对之道
- 一个经典编程面试题的“隐退”
- 文件错误关于hibernate中报Duplicate class/entity mapping org.model.User错的问题
- 软件发布的版本缩写含义RC 、RTM
- ubuntu9.04更新之后无法启动系统的解决办法
- 【FFMPEG系列】windows下编译FFMPEG篇----之一(MingW)
- php代码审计zhuru,[php 代码审计]Espcms 暴力注入
- java resource放入的文件没有生成在classes中_JAVA程序员学习笔记----mybatis深入剖析...