用除留余数法和线性探测再散列的冲突解决方法构造哈希表
时间: 2023-04-25 08:00:16 浏览: 140
哈希表是一种常用的数据结构,它可以快速地进行查找、插入和删除操作。在哈希表中,关键字通过哈希函数映射到一个固定的位置,这个位置就是该关键字在哈希表中的存储位置。
然而,由于哈希函数的设计不够完美或者数据分布不均匀等原因,可能会出现多个关键字映射到同一个位置的情况,这就是哈希冲突。为了解决哈希冲突,常用的方法有除留余数法和线性探测再散列。
除留余数法是一种简单的哈希函数设计方法,它的原理是将关键字除以一个固定的数,然后取余数作为哈希值。如果出现哈希冲突,可以通过线性探测再散列的方法解决。
线性探测再散列是一种解决哈希冲突的方法,它的原理是在哈希表中查找下一个空闲位置,如果该位置已经被占用,则继续查找下一个位置,直到找到一个空闲位置为止。如果哈希表已经被填满,就需要重新散列,即将哈希表的大小扩大一倍,然后重新插入所有的关键字。
综上所述,除留余数法和线性探测再散列是常用的哈希冲突解决方法,它们可以有效地解决哈希冲突,提高哈希表的性能。
相关问题
为班级30个人的姓名设计一个哈希表,平均查找长度的上限为2,完成相应的建表和查表。用除留余数法和线性探测再散列法
好的,我可以帮你解答这个问题。
首先,我们需要确定哈希表的大小。由于班级人数为30,为了保证平均查找长度的上限为2,我们可以将哈希表的大小设置为15,也就是说,每个人在哈希表中对应的位置可以是0到14之间的整数。
接下来,我们可以选择使用除留余数法或线性探测再散列法来建立哈希表。以下是两种方法的实现:
1. 除留余数法
除留余数法是最简单的哈希函数之一,它的计算公式为:
$h(k) = k \mod m$
其中,$k$是关键字,$m$是哈希表的大小。我们可以将每个人的姓名转换成一个整数,然后使用除留余数法计算出它在哈希表中的位置。
下面是使用除留余数法建立哈希表的示例代码:
```python
class HashTable:
def __init__(self, size):
self.size = size
self.table = [None] * size
def hash(self, key):
return key % self.size
def insert(self, key, value):
index = self.hash(key)
if self.table[index] is None:
self.table[index] = (key, value)
else:
i = (index + 1) % self.size
while i != index:
if self.table[i] is None:
self.table[i] = (key, value)
break
i = (i + 1) % self.size
def search(self, key):
index = self.hash(key)
if self.table[index] is None:
return None
elif self.table[index][0] == key:
return self.table[index][1]
else:
i = (index + 1) % self.size
while i != index:
if self.table[i] is None:
return None
elif self.table[i][0] == key:
return self.table[i][1]
i = (i + 1) % self.size
return None
```
在上面的代码中,我们使用了线性探测法来解决哈希冲突。如果某个位置已经被占用,我们就顺序往后查找,直到找到一个空位置为止。
2. 线性探测再散列法
线性探测再散列法是一种解决哈希冲突的方法,它的计算公式为:
$h(k, i) = (h'(k) + i) \mod m$
其中,$h'(k)$是第一次哈希函数的计算结果,$m$是哈希表的大小,$i$是一个变量,表示线性探测的步长。
下面是使用线性探测再散列法建立哈希表的示例代码:
```python
class HashTable:
def __init__(self, size):
self.size = size
self.table = [None] * size
def hash(self, key):
return key % self.size
def rehash(self, key, i):
return (self.hash(key) + i) % self.size
def insert(self, key, value):
i = 0
while i < self.size:
index = self.rehash(key, i)
if self.table[index] is None:
self.table[index] = (key, value)
break
i += 1
def search(self, key):
i = 0
while i < self.size:
index = self.rehash(key, i)
if self.table[index] is None:
return None
elif self.table[index][0] == key:
return self.table[index][1]
i += 1
return None
```
在上面的代码中,我们使用了线性探测再散列法来解决哈希冲突。如果某个位置已经被占用,我们就按照线性探测的步长依次往后查找,直到找到一个空位置为止。
现在,我们可以将班级30个人的姓名插入到哈希表中,并进行查找。下面是示例代码:
```python
names = ['Alice', 'Bob', 'Charlie', 'David', 'Emily', 'Frank', 'Grace', 'Henry', 'Isaac', 'Jack', 'Kate', 'Lily', 'Megan', 'Nancy', 'Oliver', 'Peter', 'Queen', 'Rose', 'Sam', 'Tom', 'Ursula', 'Victor', 'Wendy', 'Xavier', 'Yvonne', 'Zoe', 'Adam', 'Ben', 'Cathy']
# 使用除留余数法建立哈希表
hash_table1 = HashTable(15)
for i, name in enumerate(names):
hash_table1.insert(i, name)
# 使用线性探测再散列法建立哈希表
hash_table2 = HashTable(15)
for i, name in enumerate(names):
hash_table2.insert(i, name)
# 查找哈希表中的元素
print(hash_table1.search(3)) # David
print(hash_table2.search(3)) # David
```
在上面的代码中,我们先定义了30个人的姓名,然后分别使用除留余数法和线性探测再散列法建立了两个哈希表。最后,我们分别查找了哈希表中关键字为3的元素,结果都是David。
为班级30个人的姓名设计一个哈希表,平均查找长度的上限为2,完成相应的建表和查表。用除留余数法和线性探测再散列法C语言
好的,这里是使用除留余数法和线性探测再散列法建立哈希表的C语言代码:
1. 除留余数法
```c
#include <stdio.h>
#include <string.h>
#define MAX_SIZE 15
typedef struct {
int key;
char name[20];
} Item;
typedef struct {
Item items[MAX_SIZE];
} HashTable;
int hash(int key)
{
return key % MAX_SIZE;
}
void insert(HashTable *table, int key, char *name)
{
int index = hash(key);
if (table->items[index].key == -1) {
table->items[index].key = key;
strcpy(table->items[index].name, name);
} else {
int i = (index + 1) % MAX_SIZE;
while (i != index) {
if (table->items[i].key == -1) {
table->items[i].key = key;
strcpy(table->items[i].name, name);
break;
}
i = (i + 1) % MAX_SIZE;
}
}
}
char *search(HashTable *table, int key)
{
int index = hash(key);
if (table->items[index].key == -1) {
return NULL;
} else if (table->items[index].key == key) {
return table->items[index].name;
} else {
int i = (index + 1) % MAX_SIZE;
while (i != index) {
if (table->items[i].key == -1) {
return NULL;
} else if (table->items[i].key == key) {
return table->items[i].name;
}
i = (i + 1) % MAX_SIZE;
}
return NULL;
}
}
int main()
{
HashTable table = {0};
for (int i = 0; i < MAX_SIZE; i++) {
table.items[i].key = -1;
}
char *names[] = {"Alice", "Bob", "Charlie", "David", "Emily", "Frank", "Grace", "Henry", "Isaac", "Jack", "Kate", "Lily", "Megan", "Nancy", "Oliver", "Peter", "Queen", "Rose", "Sam", "Tom", "Ursula", "Victor", "Wendy", "Xavier", "Yvonne", "Zoe", "Adam", "Ben", "Cathy"};
for (int i = 0; i < 30; i++) {
insert(&table, i, names[i]);
}
char *name = search(&table, 3);
printf("%s\n", name);
return 0;
}
```
在上面的代码中,我们定义了一个哈希表结构体,其中包含了一个Item结构体数组。在insert和search函数中,我们使用了除留余数法来计算关键字在哈希表中的位置,并使用线性探测法来解决哈希冲突。在main函数中,我们先将哈希表中所有的key初始化为-1,然后依次将30个人的姓名插入到哈希表中,并查找了关键字为3的元素。
2. 线性探测再散列法
```c
#include <stdio.h>
#include <string.h>
#define MAX_SIZE 15
typedef struct {
int key;
char name[20];
} Item;
typedef struct {
Item items[MAX_SIZE];
} HashTable;
int hash(int key)
{
return key % MAX_SIZE;
}
int rehash(int key, int i)
{
return (hash(key) + i) % MAX_SIZE;
}
void insert(HashTable *table, int key, char *name)
{
int i = 0;
while (i < MAX_SIZE) {
int index = rehash(key, i);
if (table->items[index].key == -1) {
table->items[index].key = key;
strcpy(table->items[index].name, name);
break;
}
i++;
}
}
char *search(HashTable *table, int key)
{
int i = 0;
while (i < MAX_SIZE) {
int index = rehash(key, i);
if (table->items[index].key == -1) {
return NULL;
} else if (table->items[index].key == key) {
return table->items[index].name;
}
i++;
}
return NULL;
}
int main()
{
HashTable table = {0};
for (int i = 0; i < MAX_SIZE; i++) {
table.items[i].key = -1;
}
char *names[] = {"Alice", "Bob", "Charlie", "David", "Emily", "Frank", "Grace", "Henry", "Isaac", "Jack", "Kate", "Lily", "Megan", "Nancy", "Oliver", "Peter", "Queen", "Rose", "Sam", "Tom", "Ursula", "Victor", "Wendy", "Xavier", "Yvonne", "Zoe", "Adam", "Ben", "Cathy"};
for (int i = 0; i < 30; i++) {
insert(&table, i, names[i]);
}
char *name = search(&table, 3);
printf("%s\n", name);
return 0;
}
```
在上面的代码中,我们同样定义了一个哈希表结构体和一个Item结构体,但是在insert和search函数中,我们使用了线性探测再散列法来解决哈希冲突。在main函数中,我们同样先将哈希表中所有的key初始化为-1,然后依次将30个人的姓名插入到哈希表中,并查找了关键字为3的元素。