如何用关键字构建哈希表
时间: 2024-04-27 10:19:13 浏览: 7
构建哈希表的过程可以分为以下几个步骤:
1. 设定哈希函数:哈希函数将关键字映射到散列地址上。常用的哈希函数包括取模法、乘法哈希法、除留余数法等。选择哈希函数时需要考虑关键字的特点,以及散列地址的分布情况。一个好的哈希函数应该能够将关键字均匀地分布在散列地址空间中,避免冲突的发生。
2. 分配散列地址空间:根据哈希函数的返回值,将关键字分配到散列地址空间中。通常,散列地址空间是一个固定大小的数组,每个元素对应一个散列地址。
3. 解决冲突:由于哈希函数的值域通常比关键字集合的基数要小,因此会出现多个关键字被映射到同一个散列地址的情况,即发生了冲突。解决冲突的方法包括开放地址法、链地址法、再哈希法、建立公共溢出区等。其中,链地址法是最常用的解决冲突的方法。在链地址法中,每个散列地址上维护一个链表,将所有映射到该地址上的关键字存储在链表中。
4. 插入关键字:将关键字插入到对应的散列地址中。如果发生冲突,根据选择的解决冲突方法,在对应散列地址上的链表中插入该关键字即可。
5. 查找关键字:根据哈希函数计算出关键字的散列地址,在对应散列地址上的链表中查找该关键字即可。
总的来说,构建哈希表需要选择合适的哈希函数、解决冲突的方法,以及分配散列地址空间和插入、查找关键字的具体实现。
相关问题
初始化一个哈希表 HashTable。利用除留余数法构建哈希西数,并使用开放地址法解决冲突,将关键字为(12,9,15,10.8.21, 3,29,30,11,40.7的序列次存入哈希表中。 使用哈希表查找的算法查找关键字为15的数据元素
好的,让我们来一步一步地完成这个任务。
首先,我们需要定义哈希表的结构。为了方便起见,我们可以选择使用一个固定大小的数组来表示哈希表,每个数组元素将存储一个包含关键字和值的结构体。
```c
#define TABLE_SIZE 13
typedef struct {
int key;
int value;
} HashNode;
typedef struct {
HashNode nodes[TABLE_SIZE];
} HashTable;
```
接下来,我们需要实现哈希函数。这里我们选择使用除留余数法来将关键字映射为哈希表中的索引。具体来说,我们可以将关键字除以哈希表大小,然后取余数作为索引。
```c
int hash(int key) {
return key % TABLE_SIZE;
}
```
然后,我们需要实现插入数据的函数。当我们要在哈希表中插入一个新的元素时,我们首先需要计算它的哈希值,并检查该位置是否已经被占用。如果没有被占用,我们就可以直接将元素插入该位置;否则,我们需要使用开放地址法来寻找下一个可用的位置。
在这里,我们选择使用线性探测法来解决冲突。具体来说,我们从当前位置开始向后遍历哈希表,直到找到一个空闲的位置或者遍历完整个哈希表。如果找到了空闲位置,我们就可以将元素插入该位置;否则,我们将继续从开头位置开始遍历哈希表,直到找到一个可用位置。
```c
void insert(HashTable* table, int key, int value) {
int index = hash(key);
int i = index;
while (table->nodes[i].key != 0) {
i = (i + 1) % TABLE_SIZE;
if (i == index) {
printf("HashTable is full!\n");
return;
}
}
table->nodes[i].key = key;
table->nodes[i].value = value;
}
```
最后,我们需要实现查找数据的函数。当我们要在哈希表中查找一个元素时,我们首先需要计算它的哈希值,并检查该位置是否包含该元素。如果包含,我们就可以直接返回它的值;否则,我们需要使用同样的方法来寻找下一个可能包含该元素的位置。
```c
int search(HashTable* table, int key) {
int index = hash(key);
int i = index;
while (table->nodes[i].key != key) {
i = (i + 1) % TABLE_SIZE;
if (table->nodes[i].key == 0 || i == index) {
printf("Element not found!\n");
return -1;
}
}
return table->nodes[i].value;
}
```
现在,我们可以将关键字为(12,9,15,10.8.21, 3,29,30,11,40.7的序列次存入哈希表中,并使用哈希表查找的算法查找关键字为15的数据元素,代码如下:
```c
int main() {
HashTable table = {0};
int key[] = {12, 9, 15, 10, 8, 21, 3, 29, 30, 11, 40, 7};
int value[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < sizeof(key) / sizeof(int); i++) {
insert(&table, key[i], value[i]);
}
printf("Searching for key 15: %d\n", search(&table, 15));
return 0;
}
```
输出结果为:
```
Searching for key 15: 3
```
可以看到,我们成功地找到了关键字为15的数据元素,它的值为3。
题目描述 定义哈希函数为H(key) = key%11,输入表长(大于、等于11)。输入关键字集合,用线性探测再散列构建哈希表,并查找给定关键字。输入 测试次数t 每组测试数据为: 哈希表长m、关键字个数n n个关键字 查找次数k k个待查关键字 输出 对每组测试数据,输出以下信息: 构造的哈希表信息,数组中没有关键字的位置输出NULL 对k个待查关键字,分别输出:0或1(0—不成功,1—成功)、比较次数、查找成功的位置(从1开始)使用C++代码解题
以下是使用C++实现的代码:
```
#include <iostream>
#include <vector>
using namespace std;
// 定义哈希函数
int H(int key, int m) {
return key % m;
}
// 线性探测再散列构建哈希表
vector<int> hashTable(int m, int n, vector<int> keys) {
vector<int> T(m, -1); // 初始化哈希表,-1表示该位置没有关键字
for (int i = 0; i < n; i++) {
int j = 0, k = H(keys[i], m);
while (j < m && T[k] != -1) { // 线性探测查找下一个空位置
j++;
k = (k + 1) % m;
}
if (j == m) { // 哈希表已满,无法插入
cout << "哈希表已满,插入失败!" << endl;
return vector<int>(0);
} else {
T[k] = keys[i]; // 插入关键字
}
}
return T;
}
// 查找关键字
vector<int> searchKeys(vector<int> T, int k, vector<int> searchKeys) {
vector<int> result;
for (int i = 0; i < k; i++) {
int j = 0, key = searchKeys[i], pos = H(key, T.size());
while (T[pos] != -1 && T[pos] != key && j < T.size()) { // 线性探测查找关键字
j++;
pos = (pos + 1) % T.size();
}
if (T[pos] == key) { // 查找成功
result.push_back(1); // 标记为成功
result.push_back(j + 1); // 比较次数
result.push_back(pos + 1); // 成功位置
} else { // 查找失败
result.push_back(0); // 标记为失败
result.push_back(j + 1); // 比较次数
result.push_back(0); // 失败位置为0
}
}
return result;
}
int main() {
int t;
cin >> t; // 输入测试次数
while (t--) {
int m, n, k;
cin >> m >> n; // 输入哈希表长和关键字个数
vector<int> keys(n);
for (int i = 0; i < n; i++) {
cin >> keys[i]; // 输入关键字集合
}
vector<int> T = hashTable(m, n, keys); // 构造哈希表
if (T.empty()) { // 哈希表构造失败
continue;
}
for (int i = 0; i < m; i++) {
if (T[i] == -1) { // 该位置没有关键字
cout << "NULL ";
} else {
cout << T[i] << " ";
}
}
cout << endl;
cin >> k; // 输入待查关键字个数
vector<int> searchKeys(k);
for (int i = 0; i < k; i++) {
cin >> searchKeys[i]; // 输入待查关键字
}
vector<int> result = searchKeys(T, k, searchKeys); // 查找关键字
for (int i = 0; i < k; i++) {
if (result[i * 3] == 1) { // 查找成功
cout << "1 " << result[i * 3 + 1] << " " << result[i * 3 + 2] << endl;
} else { // 查找失败
cout << "0 " << result[i * 3 + 1] << " " << result[i * 3 + 2] << endl;
}
}
}
return 0;
}
```
输入格式为:
```
测试次数t
哈希表长m 关键字个数n
n个关键字
待查关键字个数k
k个待查关键字
```
输出格式为:
```
构造的哈希表信息
每个待查关键字的信息,包括0或1、比较次数、查找成功的位置
```