概念和结构

  • 散列表是根据关键码值(Key value)而直接进行访问的数据结构。
  • 若关键字为k,则其值存放在f(k)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为散列函数,按这个思想建立的表为散列表。

哈希表的操作

哈希表有三种常用操作,分别为

  1. 添加元素put(key, value)
  2. 通过键移除元素 remove(key)
  3. 由键获取值 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)];}}

哈希冲突

不同关键字的哈希函数值可能相同,这种现象称之为哈希冲突

有两种解决方法:

  1. 分离链接法
  2. 线性探查法

分离链接法

分离链接法就是将散列值相同的所有元素保留到同一个链表中。

分离链接法的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,也叫哈希表)相关推荐

  1. 数据结构--散列表 Hash Table

    文章目录 1.线性探测 哈希表代码 2.拉链法 哈希表代码 1. 散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来.可以说,如果没有数组,就没有散列表. ...

  2. 散列表(Hash Table)

    散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列 ...

  3. 什么是散列表(Hash Table)

    散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度 ...

  4. 白话算法(6) 散列表(Hash Table)从理论到实用(中)

    不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好的)方法.推动科技进步的人,永远是那些敢于问出比外行更天真.更外行的问题, ...

  5. JavaScript 数据结构与算法(二)哈希表

    本文参考文献:https://www.cnblogs.com/AhuntSun-blog/p/12636718.html 配套视频教程:https://www.bilibili.com/video/B ...

  6. 白话算法(6) 散列表(Hash Table) 从理论到实用(下)

    [澈丹,我想要个钻戒.][小北,等等吧,等我再修行两年,你把我烧了,舍利子比钻戒值钱.] --自扯自蛋 无论开发一个程序还是谈一场恋爱,都差不多要经历这么4个阶段: 1)从零开始.没有束缚的轻松感.似 ...

  7. Redis散列表(hash)使用

    Redis有5种常用的数据结构,分别为:string(字符串),list(列表),hash(哈希表或散列表),set(集合)和zset(有序集合).5种数据结构指的是作为键值对的值存在于Redis库中 ...

  8. ds哈希查找—二次探测再散列_大白话之哈希表和哈希算法

    哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...

  9. 10_JavaScript数据结构与算法(十)哈希表

    JavaScript 数据结构与算法(十)哈希表 认识哈希表 哈希表是一种非常重要的数据结构,几乎所有的编程语言都直接或者间接应用这种数据结构. 哈希表通常是基于数组实现的,但是相对于数组,它存在更多 ...

最新文章

  1. Kafka核心设计与实践原理总结:基础篇
  2. 在Linux(Ubuntu)下搭建ASP.NET Core环境并运行 继续跨平台
  3. 电信/移动/联通同台秀肌肉 集体表态:云计算市场“不能丢”!
  4. 永不示弱_永不过时的网页设计:今天和2000年的在线投资组合
  5. 数据结构(Java)-哈希表
  6. 让Linux使用malloc申请更多的内存
  7. kibana常见启动报错
  8. python读取字符串按列分配后按行读出
  9. 每日学习笔记(13)
  10. zblog mysql修改_MySQL_网上下载的Zblog模板怎么修改?,      终于下 - phpStudy
  11. 如何在海量元素中(例如 10 亿无序、不定长、不重复)快速判断一个元素是否存在?
  12. Rebase Current onto Selected
  13. ImageNet数据集的0到999Label对应的类别分别是什么
  14. ctypes调用海康威视人脸抓拍机并将抓拍的人脸上传到指定地址
  15. C Runtime Library 与 STL
  16. 斐波那契序列递归方法_斐波那契和卢卡斯序列
  17. Codeforces-715B-Complete The Graph(最短路)
  18. 【CSS 形状 (Shapes)】
  19. mPEG-OPSS MPEG-SPDP 甲氧基PEG巯基吡啶
  20. java计算机毕业设计智能推荐电影网站源码+mysql数据库+系统+lw文档+部署

热门文章

  1. vue-select-lang
  2. 面试题:String StringBufere StringBuilder 不用看
  3. CSRF 攻击的应对之道
  4. 一个经典编程面试题的“隐退”
  5. 文件错误关于hibernate中报Duplicate class/entity mapping org.model.User错的问题
  6. 软件发布的版本缩写含义RC 、RTM
  7. ubuntu9.04更新之后无法启动系统的解决办法
  8. 【FFMPEG系列】windows下编译FFMPEG篇----之一(MingW)
  9. php代码审计zhuru,[php 代码审计]Espcms 暴力注入
  10. java resource放入的文件没有生成在classes中_JAVA程序员学习笔记----mybatis深入剖析...