数据结构课程设计---哈希表

本文用于记录数据结构最终的课程设计 ---哈希表查找生日相同的同学

代码如下:

#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

所用数据信息若有侵权,请联系删除。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值