代码中的散列表使用的是开放地址法中的线性探测法来解决冲突。具体来说,当插入一个元素时,如果该元素对应的桶已经被占用,就顺序查找下一个空桶,直到找到一个空桶为止。同样的方法也适用于查找和删除元素。
线性探测法是散列表中的一种解决冲突的方法。下面是使用C++实现线性探测法的示例代码:
#include <iostream>
using namespace std;
const int TABLE_SIZE = 10; // 散列表的大小
class HashTable {
private:
int* table;
int size;
public:
HashTable() {
size = TABLE_SIZE;
table = new int[size];
for (int i = 0; i < size; i++) {
table[i] = -1; // 初始化所有的桶为空
}
}
// 哈希函数:对键值取模
int hash(int key) {
return key % size;
}
// 插入元素
void insert(int key) {
int index = hash(key);
while (table[index] != -1) { // 桶不为空,发生冲突
index = (index + 1) % size; // 线性探测下一个桶
}
table[index] = key; // 将元素存储到桶中
}
// 查找元素
bool search(int key) {
int index = hash(key);
while (table[index] != -1) { // 桶不为空,可能发生冲突
if (table[index] == key) {
return true; // 找到了元素
}
index = (index + 1) % size; // 线性探测下一个桶
}
return false; // 没有找到元素
}
// 删除元素
void remove(int key) {
int index = hash(key);
while (table[index] != -1) { // 桶不为空,可能发生冲突
if (table[index] == key) {
table[index] = -1; // 将桶标记为空
return;
}
index = (index + 1) % size; // 线性探测下一个桶
}
}
// 打印散列表
void printTable() {
for (int i = 0; i < size; i++) {
cout << "[" << i << "]: ";
if (table[i] != -1) {
cout << table[i];
}
cout << endl;
}
}
~HashTable() {
delete[] table;
}
};
int main() {
HashTable ht;
ht.insert(10);
ht.insert(22);
ht.insert(37);
ht.insert(41);
ht.insert(58);
ht.insert(72);
ht.printTable();
cout << "查找 41: " << ht.search(41) << endl;
cout << "查找 99: " << ht.search(99) << endl;
ht.remove(41);
ht.printTable();
return 0;
}
在上面的代码中,我们定义了一个 HashTable
类来表示散列表。类的成员包括散列表本身,大小和哈希函数。我们使用动态数组来表示散列表,数组的每个元素都是一个桶,可以存储一个元素。
首先,在代码中定义了一个常量 TABLE_SIZE
作为散列表的大小,并定义了一个 HashTable
类来表示散列表。 HashTable
类中包含了一个 int*
类型的数组 table
,用于存储元素;以及一个整型变量 size
,表示散列表的大小。
接着,HashTable
类定义了一个默认构造函数,用于初始化散列表。在该构造函数中,使用 new
运算符动态分配了一个大小为 TABLE_SIZE
的数组,将所有桶的初始值设为 -1
,表示该桶为空。
HashTable
类还定义了一个哈希函数 hash
,该函数接受一个整数参数 key
,返回 key
对 size
取模的结果,即 key % size
。该哈希函数将键值映射到散列表的桶中,以便进行元素的插入、查找和删除操作。
接下来,HashTable
类实现了插入元素的方法 insert
。该方法首先计算元素的哈希值,然后在散列表中查找该元素的存储位置。如果该位置已经被占用,则继续查找下一个空桶,直到找到一个空桶为止。最后,将元素存储到该空桶中。
类似地,HashTable
类还实现了查找元素的方法 search
和删除元素的方法 remove
。这两个方法使用相同的方法来计算元素的哈希值,并使用线性探测法来解决冲突。如果查找到了元素,search
方法返回 true
,否则返回 false
;如果删除了元素,则将对应桶的值设为 -1
,表示该桶为空。
最后,HashTable
类还定义了一个打印散列表的方法 printTable
,用于输出散列表中的元素。该方法遍历整个散列表,并输出每个桶的索引和对应的元素(如果该桶不为空)。
在 main
函数中,首先创建了一个 HashTable
对象 ht
。然后,依次向 ht
中插入了 6 个整数,即接下来,代码定义了一个名为“HashTable”的类。该类包含以下成员函数:
- 构造函数:创建大小为TABLE_SIZE的哈希表,用-1初始化所有桶。
- 哈希函数:接受一个整数键并返回它在哈希表中的索引,即key%size。
- 插入函数:接受一个整数键并将其插入哈希表中。如果发生冲突,它将在散列表中进行线性探测,直到找到空桶为止。
- 查找函数:接受一个整数键并在哈希表中查找该键。如果发生冲突,它将在散列表中进行线性探测,直到找到要查找的键或空桶为止。
- 删除函数:接受一个整数键并从哈希表中删除该键。如果发生冲突,它将在散列表中进行线性探测,直到找到要删除的键或空桶为止。
- 打印函数:打印哈希表中的所有桶和存储在桶中的元素。
- 析构函数:释放由哈希表使用的内存。
在main函数中,创建一个哈希表对象,插入6个元素,然后打印哈希表。接下来,它搜索两个元素(41和99),然后从哈希表中删除元素41。最后,它再次打印哈希表,显示元素41已从哈希表中删除。