学习JavaScript中的哈希表

83 阅读6分钟

JavaScript中的哈希表

哈希表是计算领域中强大的数据结构。数据结构和算法以有效解决问题而闻名。哈希表以恒定的时间(O(1))访问组件。哈希表使我们能够使用键快速找到数据。

在这篇文章中,我们将学习什么是哈希表,它们如何工作,它们的用途,以及如何在JavaScript中实现它们。

前提条件

在数据结构和算法的世界里,哈希表是很常见的。因此,我们建议读者对数据结构、JavaScript对象和数组有一个基本的了解。

哈希表概述

哈希表是一种将键与值配对的数据结构。散列表也被称为无序地图、字典或哈希图。它为键值对实现了关联数组。这是通过将键和值转换为数组的索引来实现的。

哈希表有效地提供了插入、删除和检索操作。散列函数(散列算法)接收一个键(字符串)并将其转换为一个数字。然后,它将这个数字重新映射为数组中的一个索引。不同的词被哈希函数映射为不同的数字。

散列函数是不可逆的。它是一种单向的算法。你不应该能够把一个哈希函数的结果,通过另一个函数反馈给它,并得到原始数据。

哈希表也是确定性的。反复将钥匙送入散列函数会得到相同的结果。

散列表为你提供了一种将键与值联系起来的方法。例如,每个学生在学校都有一个唯一的号码(注册号)。

一个注册号可以检索学生的详细信息。哈希表是这个问题的一个完美解决方案。因为这允许你立即得到响应。

编程语言在不同的名称下使用哈希表。

  • Java:哈希图
  • Python:哈希图字典
  • JavaScript:对象和地图

对象和地图都是JavaScript中的哈希表。

哈希表实现了地图和对象的数据结构。本文将详细介绍JavaScript中的哈希表。

哈希表实现了关联数组,这是一个将键值映射为值的系统。与许多编程语言不同,JavaScript不支持关联数组(带有命名索引的数组)。

在JavaScript中,数组使用编号的索引。

散列表如何工作

哈希表使用数组来存储数据或记录。来自哈希函数的数值被用作索引来存储数据。数据被存储在使用数字的桶中。

为了理解哈希表的工作原理,让我们通过一个假想的问题。

假设我们有一个拥有不同书籍的图书馆。你必须通过书名知道你需要的书。要找到该书所在的正确书架也是一个挑战。一个哈希表将有助于解决这个问题。

每本书都有一个唯一的编号(bk id)。我们的键是书的ID,我们的值是书名。我们将键和值对传递给我们的哈希表。它通过一个哈希函数运行键,哈希函数返回一个索引(例如3)。

哈希函数将键和值对存储在索引中。如果我们想得到一本特定的书,我们把书的ID传给哈希表。哈希函数将键映射到索引中,关于这本书的信息就被检索出来。

哈希表的平均时间复杂度是O(1)或插入、检索和删除的恒定时间。因此,哈希表是快速的,不像使用数组来获取具体信息。

数组以O(n)的速度对桶中的项目进行迭代,以找到你要找的键。

哈希表被广泛用于。

  • 数据库的索引。
  • 程序编译的关键词识别。
  • 缓存。
  • 关联数组。
  • 唯一的数据表示。

散列表的性能取决于三个基本组成部分。

  • 哈希函数。
  • 散列表的大小。
  • 碰撞处理方法。

处理碰撞

当不同的键被散列到相同的数字或索引时,就会发生碰撞。

我们怎样才能解决这个问题呢?有许多处理碰撞的方法。我们将在下面学习几种。

分离链

分离链是一种将键值对散列到桶数组中相同索引的方法。为该特定索引创建一个链接列表。

在这种策略中,你必须在这些配对之间进行迭代,以找到你要找的键。单独的链式导致效率低下。它使时间复杂度更接近于O(n)。这意味着它线性地取决于输入的大小。

Separate Chaining

线性探测

线性探测中,如果哈希指数可用,你就添加一个元素并移动到下一个位置。

Linear Probing

反洗

洗牌是重新计算存储的键值对的哈希值。然后在达到阈值时将它们移到一个更大的哈希图中。

在JavaScript中实现哈希表

在JavaScript中,哈希表实现了对象。

为了在JavaScript中实现一个哈希表,我们将。

  • 创建一个类哈希表。
  • 添加一个哈希函数。
  • 实现对键/值对的插入、检索和删除。

JavaScript哈希表

首先,让我们创建一个class HashTable.

类哈希表有两个属性,bucketssize.

class HashTable{
  constructor(size=50){
    this.buckets =  new Array(size)
    this.size = size
  }
}

哈希函数

下一步将是添加一个哈希函数。

  hash(key){
    return key.toString().length % this.size;
  }

插入方法

插入方法在哈希表中添加键/值对。为了开始,创建一个名为setItem 的方法,有两个参数,keyvalue. 用哈希函数对键进行哈希。

然后将键/值对推入桶中。我们将在桶中存储我们的数据。

setItem(key,value){
    let index = this.hash(key);

    if(!this.buckets[index]){
      this.buckets[index] = [];
    }

    this.buckets[index].push([key,value])
    return index
}

检索(Retrieve

retrieve方法帮助我们使用一个键来获取数据。创建方法getItem ,有一个参数,key 。哈希键并获得桶的索引。

检索或搜索哈希表中的数据非常快。我们可以快速获得索引。

getItem(key){
    let index = this.hash(key);
  
     if(!this.buckets[index])return null
     
        for(let bucket of this.buckets[index]){
             // key
          if(bucket [0] === key){
             // value
            return bucket [1]
           }
        }
}

这就是我们实现哈希表的完整代码。JavaScript对象被应用于哈希表中。

class HashTable{
  constructor(size=50){
    this.buckets =  new Array(size)
    this.size = size
  }

  hash(key){
    return key.toString().length % this.size;
  }
  
  // Insert data
  setItem(key,value){
    let index = this.hash(key);
    
    if(!this.buckets[index]){
      this.buckets[index] = [];
    }
    
    this.buckets[index].push([key,value])
    return index
  }

  // Search data
  getItem(key){
    let index = this.hash(key);
  
     if(!this.buckets[index])return null
     
        for(let bucket of this.buckets[index]){
             // key
          if(bucket [0] === key){
             // value
            return bucket [1]
           }
        }
  }
}

const hashTable = new HashTable();
// Insert data to the hash table
hashTable.setItem("bk101","Data structures algorithms");
hashTable.setItem("bk108","Data analytics");
hashTable.setItem("bk200","Cyber security");
hashTable.setItem("bk259","Business Intelligence");
hashTable.setItem("bk330","S/W Development");

// Search data from the hash table 
hashTable.getItem("bk101");
console.log(hashTable.getItem("bk101"));

该代码在散列表中插入数据,并使用键(书籍ID)来检索一本书的标题。该代码的工作原理如下面的视频所示。

总结

我们了解到,哈希表是使用键值对存储数据的数据结构。我们还了解到,哈希表被广泛使用,因为它们快速而高效。

总结一下。

  • 你学到了什么是哈希表。
  • 哈希表如何工作。
  • 你还学会了如何在JavaScript中实现哈希表。