本文用于记录数据结构最终的课程设计 ---哈希表查找生日相同的同学
代码如下:
#include<bits/stdc++.h>
#include<fstream>
using namespace std;
#define M 41
int a[41];//搜索时用于计数
typedef struct p{
char id[12]; //学号
char name[7]; //姓名
char sex[3]; //性别
char grade[10];//班级
char birth[8];//生日
int idex;//下文比较生日时使用
}HashTable[M]; //构建结构体,存放数据
int hash(char id[]) //用学号的后三位分析作为哈希值,这是将数据分析法和除留余数法综合起来使用
{
int d;
d=((id[8]-'0')*100+(id[9]-'0')*10+(id[10]-'0'))%M;
return d;
}
void hashTable(HashTable HT,char *filename)//建立哈希函数
{
FILE *fp;
int d;//存放哈希值
int di; //在遇到冲突的时候作为增量
int Hi;//线性探测法的得到的地址
char id[12]; //学号
char name[7]; //姓名
char sex[3]; //性别
char grade[10];//班级
char birth[5];//生日
for(int i=0;i<M;i++)//初始化数据表中的数据为空
{
strcpy(HT[i].id,"");//strcpy函数的作用是用后面的取代前面内容
strcpy(HT[i].name,"");
strcpy(HT[i].sex,"");
strcpy(HT[i].grade,"");
strcpy(HT[i].birth,"");
}//这样就完成了数据表的初始化
if((fp=fopen(filename,"r"))==NULL)//判断读取的文件是否存在,不存在时要给出语句
{
printf("文件%s不存在",filename);
exit(0);
}
int p=0;
while(!feof(fp))
{
p++;//用于记录读取数据次数,因为不写这一行的话,最后那一个数据总是被读入两遍
fscanf(fp,"%s%s%s%s%s",id,name,sex,grade,birth);//读入信息
d=hash(id);//计算哈希值
if(strcmp(HT[d].id,"")==0)//通过比较发现这个位置是空的,那么就可以放入信息
{
strcpy(HT[d].id,id);
strcpy(HT[d].name,name);
strcpy(HT[d].sex,sex);
strcpy(HT[d].grade,grade);
strcpy(HT[d].birth,birth);
}
else//如果不相等那就说明位置冲突了,要解决冲突
{
for(di=1;di<M;di++)
{
Hi=(d+di)%M;
if(strcmp(HT[Hi].id,"")==0)//通过比较发现这个位置是空的,那么就可以放入信息
{
strcpy(HT[Hi].id,id);
strcpy(HT[Hi].name,name);
strcpy(HT[Hi].sex,sex);
strcpy(HT[Hi].grade,grade);
strcpy(HT[Hi].birth,birth);
break;
}
}
}
if(p==41)//说明数据读入完毕可以结束,避免最后一行读入两次
break;
}
}
void search(HashTable HT)//找相同生日的同学
{
memset(a,0,sizeof(a));
for(int i=0;i<M;i++)
{
HT[i].idex=0;
} //将idex初始化全部为0
for(int i=0;i<M-1;i++)
{
if(HT[i].idex==0&&strcmp(HT[i].id,"")!=0)//如果说为0且这个位置数据不为空,开始比较
{
for(int j=i+1;j<M;j++)
{
if(strcmp(HT[i].birth,HT[j].birth)==0&&HT[j].idex==0&&strcmp(HT[j].id,"")!=0)
{
a[i]++;
HT[j].idex=1;//比较晚要置为1,避免后面重复
}
}
}
HT[i].idex=1;
}
for(int i=0;i<M-1;i++)
{
if(a[i]>=1)//大于等于1说明这个生日存在相同的生日的同学
{
printf("%29s:",HT[i].birth);
printf("%s",HT[i].name);
for(int j=i+1;j<M;j++)//for循环遍历找一样的
{
if(strcmp(HT[i].birth,HT[j].birth)==0)
{
printf(",");
printf("%s",HT[j].name);
}
}
}
else {
continue;
}
printf("\n");
}
}
void printHT(HashTable HT)//用于打印哈希表中的所有数据
{
for(int i=0;i<M;i++)
{
printf("%26d: %10s%10s%8s%12s%10s\n",i,HT[i].id,HT[i].name,HT[i].sex,HT[i].grade,HT[i].birth);
}
}
int main()//主函数
{
HashTable HT;
int d;
int ch;
char filename[80],id[12];
printf("%22s*********************************哈希表*********************************\n"," ");
printf("\n");
printf("%25s*构造哈希表,请输入信息所在文件名:"," ");
scanf("%s",filename);
hashTable(HT,filename);
printf("%25s*请输入你要选择的操作 1.输出哈希表全部信息\n%47s2.输出同一天生日的情况 :"," "," ");
cin>>ch;
while(ch!=3)
{
switch(ch)
{
case 1: printf("%25s*哈希表中的数据为:\n"," ");
printf("%29s: %10s %10s%10s%10s%10s\n","编号","学号","姓名","性别","班级","生日");
printf("\n");
printHT(HT);//输出所有的数据信息
break;
case 2: printf("\n");
printf("%25s*同学们同一天生日的情况为:\n"," ");
printf("\n");
search(HT);//输出相同生日的同学
break;
}
printf("\n");
printf("%25s*请输入你要选择的操作 1.输出哈希表全部信息\n%47s2.输出同一天生日的情况 :"," "," ");
cin>>ch;
}
return 0;
}
所用数据:
20200244101 马帅 男 计科201 4-15
20200544102 卜子昊 男 计科201 5-12
20200614103 程方涛 男 计科201 4-14
20200614104 王香月 女 计科201 3-28
20200714105 张贯春 女 计科201 2-19
20200754106 杨啸然 男 计科201 3-16
20201554107 关士谦 男 计科201 3-19
20201554108 刘禹 男 计科201 6-18
20201554109 乔海鑫 男 计科201 5-12
20201554110 刘翰鹏 男 计科201 9-16
20201554111 任帅豪 男 计科201 8-16
20201554112 段帅鹏 男 计科201 7-18
20201554113 许昊冉 男 计科201 6-16
20201554114 李桂宇 男 计科201 5-19
20201554115 杨磊涛 男 计科201 7-18
20201554116 梁豪杰 男 计科201 6-26
20201554117 黄兴栋 男 计科201 5-29
20201554118 张磊昂 男 计科201 7-18
20201554119 胡振坤 男 计科201 6-16
20201554120 李云飞 男 计科201 5-22
20201554121 刘钊 男 计科201 7-18
20201554122 田振 男 计科201 12-11
20201554123 刘振东 男 计科201 12-19
20201554124 詹海涛 男 计科201 11-16
20201554125 方明镜 男 计科201 5-12
20201554126 夏彩圆 男 计科201 6-16
20201554127 张风雷 男 计科201 7-18
20201554128 李潇文 女 计科201 9-16
20201554129 江嘉倩 女 计科201 7-13
20201554130 王轶兰 女 计科201 8-20
20201554131 姚怡帆 女 计科201 4-28
20201554132 王澳先 女 计科201 5-20
20201554133 杨云馨 女 计科201 4-17
20201554134 张艳飞 女 计科201 8-17
20201554135 沈帅帅 男 计科201 9-16
20201554136 杜习金 男 计科201 10-12
20201554137 卢俊辉 男 计科201 11-16
20201554138 邓佳俊 男 计科201 12-13
20201554139 王萌 男 计科201 11-20
20201554140 杨毅霄 男 计科201 11-8
20201554140 王勇 男 计科201 1-3
所用数据信息若有侵权,请联系删除。