戳这里还有其他数据结构的题目噢
https://blog.csdn.net/qq_45724947/article/details/115625130?spm=1001.2014.3001.5501
实现哈希表的构造和查找算法,要求:用除留余数法构造哈希函数,分别用一次探测再散列、二次探测再散列解决冲突。
直接上代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define max 14
#define casue 13
#define DataType int
typedef struct Hash{
int findnum;
DataType key;
}Hash;
void Createhash(Hash *hash,int kind)
{
printf("一共将要输入的数据量:\n");
int num,data;
int j,count=0;
scanf("%d",&num);
while(num>max){
printf("超出哈希表的最大长度\n");
printf("请重新输入:\n");
scanf("%d",&num);
};
getchar();
int p=1,q=1;
for(int i=0;i<num;i++){
printf("请输入第%d个数据\n",i+1);
scanf("%d",&data);
getchar();
if(kind==1){//一次探测再散列
do{
j = (data+count)%casue;
if(hash[j].key == 0){
hash[j].key=data;
hash[j].findnum=count;
count=0;
break;
}
else if(hash[j].key == data){
printf("哈希表中存在相同元素,第%d个输入元素将不存入表中\n",j);
count=0;
break;
}
count++;
}while(count!=0);
}
else{//二次探测再散列解决冲突
do{
j=data%casue;
if(count>0){//有冲突
if(count%2==1){
j+=pow(q,2);
q++;
}else{
j-=pow(p,2);
p++;
}
}
if(j<0){
j += max;
}else if(j>max){
j %= max;
}
else{
if(hash[j].key == 0){
hash[j].key=data;
if(count%2==1)
hash[j].findnum=pow(q-1,2);
else if(count==0)
hash[j].findnum=count;
else
hash[j].findnum=pow(p-1,2);
count=0;
break;
}
else if(hash[j].key == data){
printf("哈希表中存在相同元素,第%d个输入元素将不存入表中\n",j);
count=0;
break;
}
}
count++;
}while(count!=0);
}
}
}
void insert(Hash *hash,int data,int insert,int count){
hash[insert].key = data;
hash[insert].findnum = count;
}
int findkey(Hash *hash ,int val,int kind)
{
int j,i=0;
bool find = true;
if(kind == 1){
do{
j = (val+i)%casue;
if(hash[j].key == val){
find = false;
}else if(hash[j].key == 0){
find = false;
insert(hash,val,j,i+1);
j=-1;
}
i++;
if(i>max){
printf("哈希表满了\n");
exit(0);
}
}while(find);
}else{
int p=1,q=1,count=0;
do{
j=val%casue;//j是哈希表下标
//奇偶判断
if(count>0){//有冲突
if(count%2==1){
j+=pow(q,2);
q++;
}else{
j-=pow(p,2);
p++;
}
}
count++;
if(j<0){
j+=max;
}else if(j>max){
j %= max;
}else{
if(hash[j].key == val){
find = false;
}else if(hash[j].key == 0){
find = false;
insert(hash,val,j,count);
j=-1;//查找不成功
}
}
if(count>max){
printf("哈希表满了\n");
exit(0);
}
}while(find);
}
return j;
}
int main()
{
Hash hash1[max],hash2[max];
int i,val;
for(int i=0;i<max;i++){//初始化hash表
hash1[i].key=0;
hash1[i].findnum=0;
hash2[i].key=0;
hash2[i].findnum=0;
}
printf("该哈希表除余的除数为13。\n\n");
for(int k=0;k<2;k++)
{
if(k+1==1){
printf("使用 一次探测再散列方式 储存哈希\n");
Createhash(hash1,1);
//数组的下标
for(int j=0;j<max;j++){
printf("%3d ",j);
}
printf("数组的下标");
printf("\n");
//打印存入后哈希数组
for(int j=0;j<max;j++){
printf("%3d ",hash1[j].key);
}
printf("存入后的哈希数组");
printf("\n");
//打印额外解决冲突的探测值
for(int j=0;j<max;j++){
printf("%3d ",hash1[j].findnum);
}
printf("额外解决冲突的探测值");
printf("\n");
printf("请输入想要寻找的值\n");
scanf("%d",&val);
getchar();
i = findkey(hash1,val,1);
while(i==-1){//有这个元素就不插入
printf("不存在\n");
i = findkey(hash1,val,1);
break;
};
printf("所在地址: %d 值: %d 额外加的探测值: %d \n",i,hash1[i].key,hash1[i].findnum);
}
else{
printf("使用 二次探测再散列方式 储存哈希\n");
Createhash(hash2,2);
//数组的下标
for(int j=0;j<max;j++){
printf("%3d ",j);
}
printf("数组的下标");
printf("\n");
//打印存入后哈希数组
for(int j=0;j<max;j++){
printf("%3d ",hash2[j].key);
}
printf("存入后的哈希数组");
printf("\n");
//打印额外解决冲突的探测值
for(int j=0;j<max;j++){
printf("%3d ",hash2[j].findnum);
}
printf("额外解决冲突的探测值");
printf("\n");
printf("请输入想要寻找的值\n");
scanf("%d",&val);
getchar();
i = findkey(hash2,val,2);
while(i==-1){//有这个元素就不插入
printf("不存在\n");
i = findkey(hash2,val,2);
break;
};
printf("所在地址: %d 值: %d 额外加的探测值: %d \n",i,hash2[i].key,hash2[i].findnum);
}
}
return 0;
}
// 15 15 36 25 26 35 84 74 10
(代码如有雷同,可能存在借鉴他人部分代码情况)
(请不要直接复制使用。总结的代码仅供参考,希望读者借此代码自身可以理解学习)
如果代码对您有帮助,不要忘记评论收藏噢~