一.哈希表概念
哈希表(Hash Table)是一种数据结构,用于存储键值对(key-value pairs)。它通过将键(key)通过哈希函数(hash function)映射到一个特定的索引位置来实现高效的数据存储和检索。
哈希函数将不同的键映射到哈希表的不同位置上,这样可以快速地定位到对应的值,而不需要顺序查找。因此,哈希表在理想情况下具有常数时间复杂度的查找、插入和删除操作(O(1))。但在极端情况下,比如哈希冲突(两个不同的键被映射到相同的索引位置),哈希表的性能可能会退化到较差的情况。
键值对(key-value pair):是指在数据结构中用来表示一组相关信息的元素,其中一个元素是键(key),另一个元素是与该键相关联的值(value)。键值对在哈希表、字典、映射等数据结构中广泛应用,用于快速查找、插入和删除数据。
键(key):键是用来唯一标识一个值的标识符或者索引。在哈希表中,键通过哈希函数转换为一个索引,以确定值在哈希表中的存储位置。键通常是不可变的,这意味着在哈希表中一个键只能对应一个值,但一个值可以对应多个键。
值(value):值是与键相关联的数据或者信息。值可以是任何数据类型,例如整数、字符串、对象、数组等。在哈希表中,通过键可以快速查找到对应的值,从而实现高效的数据检索和更新。例如,在一个表示学生信息的哈希表中,每个学生的学号可以作为键,而学生的姓名、年龄、成绩等信息可以作为与学号对应的值。这样,通过学号作为键,可以快速地检索到对应学生的信息。这种键值对的设计使得数据的组织和检索更加灵活高效。
为了方便索引,哈希表底层实现结构是一个顺序表,每个位置被称为一个槽,存储一个键值对。以下就是一个长度为9的哈希表。
为了解决哈希冲突问题,常用的方法包括开放寻址法(open addressing)和链表法(chaining)。开放寻址法在发生冲突时,会尝试寻找下一个可用的位置来存储键值对,而链表法则是在哈希表的每个位置上维护一个链表,将哈希冲突的键值对串联在一起。
在哈希表中,解决哈希冲突的两种常见方法是开放寻址法(Open Addressing)和链表法(Chaining)。
1. 开放寻址法(Open Addressing):
- 在开放寻址法中,当发生哈希冲突时,算法会探查哈希表中其他位置,直到找到一个空闲位置为止。
- 主要的探查方法有线性探查(Linear Probing)、二次探查(Quadratic Probing)和双重散列(Double Hashing)等。
- 在线性探查中,如果位置已经被占用,则检查下一个位置,直到找到一个空闲位置。二次探查使用二次方程来计算下一个位置。双重散列是使用第二个独立的哈希函数来计算下一个位置。
- 开放寻址法的优点是不需要额外的空间来存储链表,但缺点是可能会出现聚集(clustering)现象,导致性能下降。2. 链表法(Chaining):
- 在链表法中,哈希表的每个位置都维护一个链表,当发生哈希冲突时,将新的键值对插入到对应位置的链表中。
- 当需要查找键值对时,先计算哈希值找到对应位置的链表,然后在链表中进行线性查找。
- 链表法的优点是可以避免聚集现象,但缺点是需要额外的空间来存储链表的指针,且在链表较长时查找效率可能降低。
二.哈希表实现
1.哈希表结点类定义
#include <iostream> #include <vector> #include <lis