菜单
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

DSA 哈希集合


哈希集合

哈希集合是一种形式的 哈希表 数据结构,通常包含大量元素。

使用哈希集合,我们可以非常快速地搜索、添加和删除元素。

哈希集合用于查找,以检查某个元素是否是集合的一部分。

哈希集合

0:
{{ el.name }}
1:
{{ el.name }}
2:
{{ el.name }}
3:
{{ el.name }}
4:
{{ el.name }}
5:
{{ el.name }}
6:
{{ el.name }}
7:
{{ el.name }}
8:
{{ el.name }}
9:
{{ el.name }}

哈希码

{{ sumOfAscii }} % 10 = {{ currHashCode }}


{{ resultText }}0


哈希集合根据元素的哈希码将唯一元素存储在存储桶中。

  • 哈希码: 从元素唯一值(键)生成的数字,用于确定该哈希集合元素属于哪个存储桶。
  • 唯一元素: 哈希集合不能有多个相同值的元素。
  • 存储桶: 哈希集合包含许多这样的存储桶或容器来存储元素。如果两个元素的哈希码相同,则它们属于同一个存储桶。因此,存储桶通常实现为数组或链表,因为一个存储桶需要能够容纳多个元素。

查找哈希码

哈希码由 哈希函数 生成。

上面动画中的哈希函数获取输入中的姓名,并对该姓名中每个字符的 Unicode 代码点求和。

之后,哈希函数对字符的总和进行模 10 运算(% 10)以获得 0 到 9 之间的哈希码数字。

这意味着一个姓名根据其哈希码被放入哈希集合中的十个可能存储桶之一。当我们想要从哈希集合中搜索或删除一个姓名时,会生成并使用相同的哈希码。

只要对应的存储桶中只有一个姓名,哈希码就能提供即时访问。

Unicode 代码点: 计算机中的一切都以数字形式存储,Unicode 代码点是每个字符都存在的唯一数字。例如,字符 A 的 Unicode 代码点是 65。在上面的模拟中试试看。有关字符如何表示为数字的信息,请参阅 此页面

模运算 (Modulo):一种数学运算,在大多数编程语言中表示为 %(或数学中的 \(mod\))。模运算将一个数字除以另一个数字,并给出余数。因此,例如,7 % 3 将给出余数 1。(将 7 个苹果分给 3 个人,意味着每个人得到 2 个苹果,剩下 1 个苹果。)


哈希集合中的直接访问

在上面的哈希集合中搜索 Peter,意味着会生成哈希码 2512 % 10),这将直接将我们引导到 Peter 所在的存储桶。如果那个存储桶里只有这一个名字,我们会立即找到 Peter

在这些情况下,我们说哈希集合在搜索、添加和删除元素方面具有常数时间 \(O(1)\),这非常快。

但是,如果我们搜索 Jens,我们需要搜索该存储桶中的其他名字,然后才能找到 Jens。在最坏的情况下,所有名字都落入同一个存储桶,而我们要搜索的名字是最后一个。在这种最坏的情况下,哈希集合的时间复杂度为 \(O(n)\),与数组和链表的时间复杂度相同。

为了保持哈希集合的快速性,因此拥有一个能够将元素均匀分布到存储桶中的哈希函数,并拥有大约与哈希集合元素数量相等的存储桶数量非常重要。

拥有比哈希集合元素多得多的存储桶会浪费内存,而拥有比哈希集合元素少得多的存储桶会浪费时间。


哈希集合实现

Python 中的哈希集合通常通过使用 Python 自己的 set 数据类型 来实现,但为了更好地理解哈希集合的工作原理,这里我们不使用它。

要在 Python 中实现哈希集合,我们创建一个名为 SimpleHashSet 的类。

SimpleHashSet 类中,我们有一个用于初始化哈希集合的 __init__ 方法,一个用于哈希函数的 hash_function 方法,以及用于基本哈希集合操作的方法:addcontainsremove

我们还创建了一个 print_set 方法,以便更好地查看哈希集合的外观。

示例

class SimpleHashSet:
    def __init__(self, size=100):
        self.size = size
        self.buckets = [[] for _ in range(size)]  # A list of buckets, each is a list (to handle collisions)

    def hash_function(self, value):
        # Simple hash function: sum of character codes modulo the number of buckets
        return sum(ord(char) for char in value) % self.size

    def add(self, value):
        # Add a value if it's not already present
        index = self.hash_function(value)
        bucket = self.buckets[index]
        if value not in bucket:
            bucket.append(value)

    def contains(self, value):
        # Check if a value exists in the set
        index = self.hash_function(value)
        bucket = self.buckets[index]
        return value in bucket

    def remove(self, value):
        # Remove a value
        index = self.hash_function(value)
        bucket = self.buckets[index]
        if value in bucket:
            bucket.remove(value)

    def print_set(self):
        # Print all elements in the hash set
        print("Hash Set Contents:")
        for index, bucket in enumerate(self.buckets):
            print(f"Bucket {index}: {bucket}")

使用 SimpleHashSet 类,我们可以创建与本页顶部相同的哈希集合。

示例

class SimpleHashSet:
    def __init__(self, size=100):
        self.size = size
        self.buckets = [[] for _ in range(size)]  # A list of buckets, each is a list (to handle collisions)

    def hash_function(self, value):
        # Simple hash function: sum of character codes modulo the number of buckets
        return sum(ord(char) for char in value) % self.size

    def add(self, value):
        # Add a value if it's not already present
        index = self.hash_function(value)
        bucket = self.buckets[index]
        if value not in bucket:
            bucket.append(value)

    def contains(self, value):
        # Check if a value exists in the set
        index = self.hash_function(value)
        bucket = self.buckets[index]
        return value in bucket

    def remove(self, value):
        # Remove a value
        index = self.hash_function(value)
        bucket = self.buckets[index]
        if value in bucket:
            bucket.remove(value)

    def print_set(self):
        # Print all elements in the hash set
        print("Hash Set Contents:")
        for index, bucket in enumerate(self.buckets):
            print(f"Bucket {index}: {bucket}")

# Creating the Hash Set from the simulation
hash_set = SimpleHashSet(size=10)

hash_set.add("Charlotte")
hash_set.add("Thomas")
hash_set.add("Jens")
hash_set.add("Peter")
hash_set.add("Lisa")
hash_set.add("Adele")
hash_set.add("Michaela")
hash_set.add("Bob")

hash_set.print_set()

print("\n'Peter' is in the set:",hash_set.contains('Peter'))
print("Removing 'Peter'")
hash_set.remove('Peter')
print("'Peter' is in the set:",hash_set.contains('Peter'))
print("'Adele' has hash code:",hash_set.hash_function('Adele'))
运行示例 »


×

联系销售

如果您想将 W3Schools 服务用于教育机构、团队或企业,请发送电子邮件给我们
sales@w3schools.com

报告错误

如果您想报告错误,或想提出建议,请发送电子邮件给我们
help@w3schools.com

W3Schools 经过优化,旨在方便学习和培训。示例可能经过简化,以提高阅读和学习体验。教程、参考资料和示例会不断审查,以避免错误,但我们无法保证所有内容的完全正确性。使用 W3Schools 即表示您已阅读并接受我们的使用条款Cookie 和隐私政策

版权所有 1999-2024 Refsnes Data。保留所有权利。W3Schools 由 W3.CSS 提供支持