数据结构,查找和排序(快排、直接插入排序、堆排序、散列表拉链法、折半查找)

这次的实验要求很多也很麻烦,到现在我也不确定我的Hash表查找是不是正确的。

实验要求:

设计并实现一个新冠疫苗接种信息管理系统(假设该系统面向需要接种两剂的疫苗)。要求定义一个包含接种者的身份证号、姓名、已接种了几剂疫苗、第一剂接种时间、第二剂接种时间等信息的顺序表,系统至少包含以下功能:

(1)逐个显示信息表中疫苗接种的信息;

(2)两剂疫苗接种需要间隔14~28天,输出目前满足接种第二剂疫苗的接种者信息;

(3)给定一个新增接种者的信息,插入到表中指定的位置;

(4)分别删除指定位置和给定接种者身份证号的记录;

(5)利用直接插入排序或者折半插入排序按照身份证号进行排序;

(6)分别利用快速排序和堆排序按照第一剂接种的时间进行排序;

(7)根据身份证号进行折半查找,若查找成功,则返回此接种者的信息;

(9)为提高检索效率,要求利用利用接种者的姓氏为关键字建立哈希表,并利用链地址法处理冲突。给定接种者的身份证号或姓名,查找疫苗接种信息,并输出冲突次数和平均查找长度;

(10)提供用户菜单,方便选择执行功能。可以设计成一级或多级菜单。所有功能都可重复执行。

结构体定义:(包括全局变量及宏定义)

#define max 15//最大存储数量
#define Max 100//哈希表下标最大值
int cur=9;//当前最大存储数组下标(主要用来添加信息)
int Conflict=0;//冲突数
struct time1{//时间类型
  int year;
  int mon;
  int day;
};
struct info{//接种信息类型
	long long id;
	char name[10];
	int count;
	struct time1 tm1;
	struct time1 tm2;
	int time;
};
typedef struct Lnode{//链表
	struct info data;
	struct Lnode*next;
}*Linklist,Lnode;

一、直接插入排序(具体应用场景不同,代码也不太一样)

void insertsort(int n,struct info (&info)[max]){//直接插入排序身份证号
    struct info temp;//中间变量
    int i=0,j=0;
	for(i=1;i<=n;i++)
		if(info[i].id<info[i-1].id){
		temp=info[i];
		for(j=i-1;j>=0&&info[j].id>temp.id;j--)
		info[j+1]=info[j];
		info[j+1]=temp;
	}
	}

二、快速排序


void quicksort(struct info (&info)[max],int left,int right){//快排第一剂时间
	 struct info temp;//中间变量
	  struct info pivot;//中轴变量
	 counttime(info);
	  int i,j;
	if(left>right)return;
	pivot=info[left];
	i=left;
	j=right;
  while(i<j){
    while(pivot.time>=info[i].time&&i<right)//这里的time在前面的结构体中已经说明但在调用时
                                            //要初始化一下
	i++;  
    while(pivot.time<info[j].time)
    j--;
    if(i<j){
    temp=info[i];
    info[i]=info[j];
    info[j]=temp;
	}
    }
    info[left]=info[j];
	info[j]=pivot;	
	quicksort(info,left,j-1);
	quicksort(info,j+1,right);
	}

三、堆排序

void swap(struct info (&info)[max], int i,int j){//交换函数
   struct info temp=info[i];
   info[i]=info[j];
   info[j]=temp;
}
void adjust(struct info (&info)[max], int m, int n){//调整树的结构
    int i=m;
    int j=(i*2)+1;
   while(j<=n){
    if(j+1<=n&&info[j].time<info[j+1].time) 
        j++;
    if(info[i].time>info[j].time)
        return;
    else{
        swap(info,i,j);
        i=j;            
		j=(i*2)+1;
        }
}
}
void heapsort(struct info (&info)[max], int len){//总的排序函数
    int i;
    counttime(info);
    for (i=len/2-1;i>=0;i--)
    adjust(info,i,len-1);
    for (i=len-1;i>0;i--) 
    {
    swap(info,0,i);
    adjust(info,0,i-1);
    }
}

四、折半查询(比较简单,但需要先排序)

void halfinterval(struct info (&info)[max]){//二分查找
insertsort(cur,info);
long long target;
  cout<<"输入要查找的身份证号:";
  cin>>target;
 int left=0,right=cur;
 int mid;
    while(left<=right){
	mid=(left+right)/2;
	if (info[mid].id>target)
	right=mid-1;
	else if(info[mid].id<target)
	left=mid+1;
	else
	break;}
	if(left<=right){
    printf("信息如下\n");
    printfinfo1(info[mid]);
	}
	else
	printf("查无此人\n");
}

五、散列表(具体看代码)

1.散列表创建

/*
*看了很多利用姓名设置
*哈希表的,都是先写好
*一个结构体存一些姓名
*很麻烦也不全面,没办
法输入汉字都是用拼音
*用强转将汉字转为数字。
*/
int Hashcode(char n[10]){//求哈希码
	int code=0;                         //不太了解编码,
	code=abs((int)n[0])+abs((int)n[1]); //汉字前两位都是负数,
	return code%100;                        //后两位是零不知道为什么。
}
void intiHashTable(struct Lnode (&Hash)[Max]){//初始化哈希表
	for(int i=0;i<Max;i++)
	Hash[i].next=NULL;
}
void createHashTable(struct info info[max],struct Lnode (&Hash)[Max]){//链地址法
	intiHashTable(Hash);
	int sum=0;
	for(int i=0;i<=cur;i++){
	struct Lnode*n=(Linklist)malloc(sizeof(Lnode));
	n->data=info[i];
	n->next=NULL;
	int code=Hashcode(info[i].name);
	if(Hash[code].next==NULL){//不冲突
	Hash[code].next=n;
	sum++;
}
	else{//冲突
	int i=1;
	Conflict++;
	sum+=2;
	struct Lnode *n1=(Linklist)malloc(sizeof(Lnode));
	n1=Hash[code].next;
	while(n1->next!=NULL){
    sum+=i++;
    n1=n1->next;}
    n1->next=n;
	}
}
float num=(float)sum/(cur+1);
cout<<"冲突次数:"<<Conflict<<endl;
cout<<"平均查找长度:"<<num<<endl;
}

2.散列表查找

void Hashselect(char *name,struct Lnode Hash[Max]){
	    int code=Hashcode(name);
	    if(Hash[code].next==NULL){
	    cout<<"查找失败"<<endl;
	    return;
		}
		if(strcmp(Hash[code].next->data.name,name)==0){
		printfinfo1(Hash[code].next->data);
		return;
		}
		else{
		cout<<1<<endl;
		struct Lnode *n1=(Linklist)malloc(sizeof(Lnode));
	    n1=Hash[code].next;
	    while(n1){
	    if(strcmp(n1->data.name,name)==0){
	    printfinfo1(n1->data);
	    return;
	    }
	    n1=n1->next;
		}
	    }
	    
	cout<<"查找失败"<<endl;
	return;
}

实验代码放在阿里云盘了。

  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值