用哈希表来实现的存储方式:
int hash(KeyType name) {
int address = 0;
for (int i = 0; name[i] != '\0'; i++) {
address += name[i];
}
return address % NUM;
}
将名字定义为关键字,将名字的每一个字符的ASKII码值都相加起来,最后对10取余
void Insert_HT(HashTable HT) {
HNode* p = (HNode*)malloc(sizeof(HNode));
if (p == NULL) {
printf("创建失败\n");
return;
}
printf("人名: ");
scanf("%s", p->name);
HNode* result = Search_HT(HT, p->name);
while (result != NULL) {
printf("人名重复,请重新输入!\n");
printf("人名: ");
scanf("%s", p->name);
result = Search_HT(HT, p->name);
}
printf("电话1: ");
scanf("%s", p->phone1);
while (CheckPhone(HT, p->phone1)) {
printf("电话号码已存在,请重新输入\n");
printf("电话1: ");
scanf("%s", p->phone1);
}
printf("电话2: ");
scanf("%s", p->phone2);
while (CheckPhone(HT, p->phone2)) {
printf("电话号码已存在,请重新输入\n");
printf("电话2: ");
scanf("%s", p->phone2);
}
printf("QQ号: ");
scanf("%s", p->qq);
while (CheckQQ(HT, p->qq)) {
printf("QQ已存在,请重新输入\n");
printf("QQ: ");
scanf("%s", p->qq);
}
int address = hash(p->name);
p->next = HT[address];
HT[address] = p;
}
在添加中,如果有人名,电话,qq重复的情况会提示并重新输入
void Modify_HT(HashTable HT, KeyType key) {
HNode* p = Search_HT(HT, key);
if (p != NULL) {
HNode* new_node = (HNode*)malloc(sizeof(HNode));
if (new_node == NULL) {
printf("内存分配失败\n");
return;
}
printf("请输入新的姓名:");
scanf("%s", new_node->name);
HNode* result = Search_HT(HT, new_node->name);
while (result != NULL) {
printf("人名重复,请重新输入!\n");
printf("人名: ");
scanf("%s", new_node->name);
result = Search_HT(HT, new_node->name);
}
printf("电话1: ");
scanf("%s", new_node->phone1);
while (CheckPhone(HT, new_node->phone1)) {
printf("电话号码已存在,请重新输入\n");
printf("电话1: ");
scanf("%s", new_node->phone1);
}
printf("电话2: ");
scanf("%s", new_node->phone2);
while (CheckPhone(HT, new_node->phone2)) {
printf("电话号码已存在,请重新输入\n");
printf("电话2: ");
scanf("%s", new_node->phone2);
}
printf("QQ号: ");
scanf("%s", new_node->qq);
while (CheckQQ(HT, new_node->qq)) {
printf("QQ已存在,请重新输入\n");
printf("QQ: ");
scanf("%s", new_node->qq);
}
int new_hash = hash(new_node->name); // 重新计算哈希值
// 从原位置删除
Delete_HT(HT, key);
// 插入到新位置
new_node->next = HT[new_hash];
HT[new_hash] = new_node;
printf("信息修改成功!\n");
}
else {
printf("没有找到此人!\n");
}
}
删除操作需要对关键字(名字)也需要进行更改,但是对关键字进行修改后,需要对输入的元素的位置重新进行位置上的查找插入,将原来的位置删除.
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NUM 10
typedef char KeyType[10];
typedef struct HNode {
KeyType name;
char phone1[15];
char phone2[15];
char qq[15];
struct HNode* next;
} HNode;
typedef HNode* HashTable[NUM];
void Create_HT(HashTable HT) {
for (int i = 0; i < NUM; i++) {
HT[i] = NULL;
}
}
int hash(KeyType name) {
int address = 0;
for (int i = 0; name[i] != '\0'; i++) {
address += name[i];
}
return address % NUM;
}
HNode* Search_HT(HashTable HT, KeyType key) {
int address = hash(key);
HNode* p = HT[address];
while (p != NULL) {
if (strcmp(p->name, key) == 0) {
return p;
}
p = p->next;
}
return NULL;
}
int CheckPhone(HashTable HT, char* phone) {
for (int i = 0; i < NUM; i++) {
HNode* temp = HT[i];
while (temp != NULL) {
if (strcmp(temp->phone1, phone) == 0 || strcmp(temp->phone2, phone) == 0) {
return 1;
}
temp = temp->next;
}
}
return 0;
}
int CheckQQ(HashTable HT, char* qq) {
for (int i = 0; i < NUM; i++) {
HNode* temp = HT[i];
while (temp != NULL) {
if (strcmp(temp->qq, qq) == 0) {
return 1;
}
temp = temp->next;
}
}
return 0;
}
void Insert_HT(HashTable HT) {
HNode* p = (HNode*)malloc(sizeof(HNode));
if (p == NULL) {
printf("创建失败\n");
return;
}
printf("人名: ");
scanf("%s", p->name);
HNode* result = Search_HT(HT, p->name);
while (result != NULL) {
printf("人名重复,请重新输入!\n");
printf("人名: ");
scanf("%s", p->name);
result = Search_HT(HT, p->name);
}
printf("电话1: ");
scanf("%s", p->phone1);
while (CheckPhone(HT, p->phone1)) {
printf("电话号码已存在,请重新输入\n");
printf("电话1: ");
scanf("%s", p->phone1);
}
printf("电话2: ");
scanf("%s", p->phone2);
while (CheckPhone(HT, p->phone2)) {
printf("电话号码已存在,请重新输入\n");
printf("电话2: ");
scanf("%s", p->phone2);
}
printf("QQ号: ");
scanf("%s", p->qq);
while (CheckQQ(HT, p->qq)) {
printf("QQ已存在,请重新输入\n");
printf("QQ: ");
scanf("%s", p->qq);
}
int address = hash(p->name);
p->next = HT[address];
HT[address] = p;
}
void Delete_HT(HashTable HT, KeyType key) {
int address = hash(key);
HNode* p = HT[address];
HNode* prev = NULL;
while (p != NULL) {
if (strcmp(p->name, key) == 0) {
if (prev == NULL) {
HT[address] = p->next;
}
else {
prev->next = p->next;
}
free(p);
return;
}
prev = p;
p = p->next;
}
}
void Modify_HT(HashTable HT, KeyType key) {
HNode* p = Search_HT(HT, key);
if (p != NULL) {
HNode* new_node = (HNode*)malloc(sizeof(HNode));
if (new_node == NULL) {
printf("内存分配失败\n");
return;
}
printf("请输入新的姓名:");
scanf("%s", new_node->name);
HNode* result = Search_HT(HT, new_node->name);
while (result != NULL) {
printf("人名重复,请重新输入!\n");
printf("人名: ");
scanf("%s", new_node->name);
result = Search_HT(HT, new_node->name);
}
printf("电话1: ");
scanf("%s", new_node->phone1);
while (CheckPhone(HT, new_node->phone1)) {
printf("电话号码已存在,请重新输入\n");
printf("电话1: ");
scanf("%s", new_node->phone1);
}
printf("电话2: ");
scanf("%s", new_node->phone2);
while (CheckPhone(HT, new_node->phone2)) {
printf("电话号码已存在,请重新输入\n");
printf("电话2: ");
scanf("%s", new_node->phone2);
}
printf("QQ号: ");
scanf("%s", new_node->qq);
while (CheckQQ(HT, new_node->qq)) {
printf("QQ已存在,请重新输入\n");
printf("QQ: ");
scanf("%s", new_node->qq);
}
int new_hash = hash(new_node->name); // 重新计算哈希值
// 从原位置删除
Delete_HT(HT, key);
// 插入到新位置
new_node->next = HT[new_hash];
HT[new_hash] = new_node;
printf("信息修改成功!\n");
}
else {
printf("没有找到此人!\n");
}
}
void Print_HT(HashTable HT) {
for (int i = 0; i < 10; i++) {
printf("%d号: ", i);
HNode* p = HT[i];
while (p != NULL) {
printf("名字: %s, 电话1: %s,电话2: %s, QQ: %s\n -> ", p->name, p->phone1, p->phone2, p->qq);
p = p->next;
}
printf("NULL\n");
}
}
void OperateMenu(HashTable HT) {
int choice;
do {
printf("************ 欢迎使用哈希表操作菜单 ************\n");
printf("1. 插入数据\n");
printf("2. 删除数据\n");
printf("3. 查找数据\n");
printf("4. 修改数据\n");
printf("5. 打印哈希表\n");
printf("0. 退出\n");
printf("********************************************\n");
printf("请输入您的选择:");
scanf("%d", &choice);
switch (choice) {
case 1:
Insert_HT(HT);
break;
case 2:
{
KeyType key;
printf("请输入要删除的人名:");
scanf("%s", key);
HNode* result = Search_HT(HT, key);
if (result != NULL) {
Delete_HT(HT, key);
}
else {
printf("没有找到此人!\n");
}
}
break;
case 3:
{
KeyType key;
printf("请输入要查找的人名:");
scanf("%s", key);
HNode* result = Search_HT(HT, key);
if (result != NULL) {
printf("找到了,电话1:%s,电话2:%s,QQ:%s\n", result->phone1, result->phone2, result->qq);
}
else {
printf("没有找到此人!\n");
}
}
break;
case 4:
{
KeyType key;
printf("请输入要修改的人名:");
scanf("%s", key);
HNode* result = Search_HT(HT, key);
if (result != NULL) {
Modify_HT(HT, key);
}
else {
printf("没有找到此人!\n");
}
}
break;
case 5:
Print_HT(HT);
break;
case 0:
printf("程序已退出\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (choice != 0);
}
int main() {
HashTable HT;
Create_HT(HT);
OperateMenu(HT);
return 0;
}