使用快排和双链表的实验室管理系统

使用快排和双链表的实验室管理系统

能够实现以下操作:添加,删除,查询人员信息,更新人员打卡情况,打印人员信息时的排序是按照打卡时长由大到小进行排序,如果打卡时长相同则按照学号先后排序。不多说,直接上码,注释详细到抓只猪来都能看懂

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//人员信息结构体
typedef struct STU {
	unsigned long long id;  //学号
	char name[20];  //姓名
	char temp0[2];   //解决莫名其妙的数组越界问题
	char major[20];  //专业
	float time;  //打卡时间
}STU;

//链表节点
typedef struct LNode {
	struct LNode* prior;   //前节点
	STU   data;         //数据域
	struct LNode* next;   //后节点

}LNode, * LinkList;

char printMenu();//打印主菜单
char printSub();//打印查询菜单
void addStuInfo(head);//输入人员信息
void insert(head, e);//插入人员信息
void outPutInfo(head);//输出人员信息
void reNewTime(head);//更新人员打卡时长
void deleteThem(head);//删除人员信息
void research_1(head, e);//根据学号查询
void research_2(head, e);//根据姓名查询
void research_3(head, e);//根据专业查询
void research_4(head, e);//根据打卡时长查询
LNode * LastPtr(head);//尾地址查询
void toSort(LNode * head, LinkList low, LinkList high);//快排
LNode * partion(LNode * head, LinkList low, LinkList high);//快排求中轴
void quicksort(head);//快排完成后对相同时长的信息再排序
void exchange(low,high);//我就纳闷了,为什么不允许我直接交换data???
void reply();//任意键返回(因为用了太多的清屏,不加个步骤就会把要显示的东西瞬间略过.....
STU e;
int menuID;//菜单栏选项,同样要求全局变量
int stuCount = 0;//人数,因为函数写太多了所以只能写成全局变量

int main()
{
	LNode* head;
	head = (LinkList)malloc(sizeof(LNode));
	head->next = NULL;
	head->prior = NULL;
	while (1) {
		menuID = printMenu();
		switch (menuID) {
		case '1': addStuInfo(head); break;
		case '2': insert(head, e); break;
		case '3': deleteThem(head, e); break;
		case '5': outPutInfo(head); break;
		case '6': reNewTime(head); break;
		case '0': exit(EXIT_SUCCESS); break;
		case '4':
			while (1) {
				menuID = printSub();
				switch (menuID) {
				case '1': research_1(head, e); break;
				case '2': research_2(head, e); break;
				case '3': research_3(head, e); break;
				case '4': research_4(head, e); break;
				}
				if (menuID == '0') break;
			}
		}
	}
	return 0;
}

//打印主菜单
char printMenu() {
	char menuID;
	system("cls");//清屏
	printf("*****欢迎使用实验室人员信息管理系统(当前共已录入%02d名人员信息)*****\n", stuCount);
	printf("*                                                                 *\n");
	printf("*                ---------------------------------                *\n");
	printf("*                |        GOD CALLS ME GOD       |                *\n");
	printf("*                ---------------------------------                *\n");
	printf("*                                                                 *\n");
	printf("*                (1)添加人员信息                                  *\n");
	printf("*                (2)插入人员信息                                  *\n");
	printf("*                (3)删除人员信息(根据学号)                        *\n");
	printf("*                (4)查询人员信息                                  *\n");
	printf("*                (5)显示所有人员信息                              *\n");
	printf("*                (6)更新人员打卡时长                              *\n");
	printf("*                (0)退出                                          *\n");
	printf("*                                                                 *\n");
	printf("*******************************************************************\n");
	fflush(stdin);//清空缓冲区以避免读取到其他东西
	menuID = getchar();
	return menuID;
}

//打印查询菜单
char printSub() {
	char menuID;
	system("cls");//清屏
	printf("****************查询人员信息(当前共有%02d名人员)*****************\n", stuCount);
	printf("*                                                                 *\n");
	printf("*                (1)根据学号查询                                  *\n");
	printf("*                (2)根据姓名查询                                  *\n");
	printf("*                (3)根据专业查询                                  *\n");
	printf("*                (4)根据打卡时长查询                              *\n");
	printf("*                (0)返回主菜单                                    *\n");
	printf("*                                                                 *\n");
	printf("*******************************************************************\n");
	fflush(stdin);//清空缓冲区以避免读取到其他东西
	menuID = getchar();
	return menuID;
}
//添加人员信息
void addStuInfo(LNode* head) {
	LinkList p, r;  //p指向新结点;r指向当前链表的尾结点
	int i, n;  //n表示人员数目
	r = head;
	printf("请输入人数:");
	scanf("%d", &n);
	stuCount = n;
	printf("请输入下列信息:\n");
	for (i = 1; i <= n; i++)
	{
		p = (LinkList)malloc(sizeof(LNode));
		p->next = NULL;
		printf("学号:\n");
		scanf("%llu", &p->data.id);
		printf("姓名:");
		scanf("%s", p->data.name);
		printf("专业:");
		scanf("%s", p->data.major);
		printf("打卡时长(小时):");
		scanf("%f", &p->data.time);
		p->prior = r;
		r->next = p;
		r = r->next;
		printf("-----------------------------------------\n");
	}
	printf("********************************************************\n");
}

//人员信息插入(尾部插入)
void insert(LNode* head, STU e)
{
	LinkList p, r;
	r = head;
	printf("请输入插入学生的信息:\n");
	printf("学号:\n");
	scanf("%llu", &e.id);
	printf("姓名:\n");
	scanf("%s", e.name);
	printf("专业:\n");
	scanf("%s", e.major);
	printf("打卡时长:\n");
	scanf("%f", &e.time);
	while (r->next != NULL)
	{
		r = r->next;
	}
	p = (LinkList)malloc(sizeof(LNode));
	p->data = e;
	p->next = NULL;
	p->prior = r;
	r->next = p;
	printf("插入成功!\n");
	stuCount++;
	reply();
}

//输出人员信息
void outPutInfo(LNode* head)
{
	LinkList p,low,high;
	p = head;
	if(head->next==NULL){
        printf("尚未录入任何人!");
        reply();
        return;
	}
	low=head->next;
	high=LastPtr(head);
	toSort(head,low,high);
	quicksort(head);
	system("cls");
	printf("开始输出人员信息:\n\n");
	printf("学号\t\t姓名\t\t专业\t\t打卡时长\n");
	while (high->prior != NULL)
	{
		printf("%llu\t%s\t\t%s\t\t%.2f\t\n", high->data.id, high->data.name, high->data.major, high->data.time);
		high = high->prior;
	}
	reply();
}



//更新人员打卡时长
void reNewTime(LNode* head)
{
	LinkList r;
	r = head;
	while (r->next != NULL) {
		r = r->next;
		printf("原来%s的打卡时长为%.2f小时\n请输入新的打卡时长:", r->data.name, r->data.time);
		scanf("%f", &r->data.time);
		printf("\n输入成功!,现在%s的打卡时间为%.2f小时!\n", r->data.name, r->data.time);
	}
	printf("全部人员的打卡情况已经更新完毕!\n");
	reply();

}

//人员信息删除
void deleteThem(LNode* head)
{
	LinkList temp, r;
	int i;
	r = head;
	printf("请输入你要删除的人员学号:\n");
	scanf("%d", &i);
	while (r->next != NULL && r->data.id != i)
		r = r->next;
	if (r->data.id != i)
	{
		printf("删除失败!学号不存在!\n");
		return;
	}
	if (r->next == NULL) {
		r = r->prior;
		r->next = NULL;
		printf("删除成功!\n");
		stuCount--;
		reply();
	}
	else {
		temp = r;
		r = r->prior;
		r->next = temp->next;
		temp = temp->next;
		temp->prior = r;
		printf("删除成功!\n");
		stuCount--;
		reply();
	}
}

//人员信息查询
void research_1(LNode* head, STU e)
{
	LinkList p;
	p = head;
	printf("请输入查找的学号:\n");
	scanf("%llu", &e.id);
	while ((p->next != NULL) && e.id != p->data.id)
	{
		p = p->next;
	}
	if (e.id == p->data.id)
		printf("学号 %llu\t 姓名  %s\t 专业  %s\t 打卡时长  %.2f\n", p->data.id, p->data.name, p->data.major, p->data.time);
	else
		printf("尚未录入该人员信息!");
	reply();
}
void research_2(LNode* head, STU e)
{
    int a=0;
	LinkList p;
	p = head;
	printf("请输入查找的姓名:\n");
	scanf("%s", e.name);
loop1:while ((p->next != NULL) && strcmp(e.name, p->data.name) != 0)
{
	p = p->next;
}
if (strcmp(e.name, p->data.name) == 0){
printf("学号 %llu\t 姓名  %s\t 专业  %s\t 打卡时长  %.2f\n", p->data.id, p->data.name, p->data.major, p->data.time);
a++:}
if (p->next != NULL) {
	p = p->next;//防止有重名人员信息未被显示
	goto loop1;
}
if(i==0)
printf("尚未录入该人员信息!");
reply();
}
void research_3(LNode* head, STU e)
{   int a=0;
	LinkList p;
	p = head;
	printf("请输入查找的专业:\n");
	scanf("%s", e.major);
loop2:while ((p->next != NULL) && strcmp(e.major, p->data.major) != 0)
{
	p = p->next;
}
if (strcmp(e.major, p->data.major) == 0){
printf("学号 %llu\t 姓名  %s\t 专业  %s\t 打卡时长  %.2f\n", p->data.id, p->data.name, p->data.major, p->data.time);
a++;}

if (p->next != NULL) {
	p = p->next;//同一专业显示全部人员
	goto loop2;
}
if(i==0)
printf("尚未录入该人员信息!");
reply();
}
void research_4(LNode* head, STU e)
{   int a=0;
	LinkList p;
	p = head;
	printf("请输入查找的打卡时长:\n");
	scanf("%f", &e.time);
loop3:while ((p->next != NULL) && e.time != p->data.time)
{
	p = p->next;
}
if (e.time == p->data.time){
printf("学号 %llu\t 姓名  %s\t 专业  %s\t 打卡时长  %.2f\n", p->data.id, p->data.name, p->data.major, p->data.time);
a++;}
if (p->next != NULL) {
	p = p->next;//防止有打卡时长相同的信息未被显示
	goto loop3;
}
if(i==0)
printf("尚未录入该人员信息!");
reply();
}

//获取尾地址
LNode * LastPtr(LNode* head) {
	LinkList p;
	p = head;
	while (p->next != NULL)
		p = p->next;
	return p;
}
//快排中轴寻找
LNode * partion(LNode * head, LinkList low, LinkList high)
{
 float pivot = 0;
 if ( !head )
 {
  printf("错误,头节点为空!/n");
  exit(1);
 }
 if ( !head->next )
 {
  return head->next;//就一个元素
 }
 pivot = low->data.time;
 while ( low != high )
 {
  //从后面往前换
  while ( low != high && high->data.time >= pivot )
  {
   high = high->prior;
  }
  //交换high low
  exchange(low,high);
  //从前往后换
  while ( low != high && low->data.time <= pivot )
  {
   low = low->next;
  }
  //交换high low
  exchange(low,high);
 }
 return low;
}
//快排
void toSort(LNode * head, LinkList low, LinkList high)
{
 LNode * temp = NULL;
 temp = partion(head, low, high);
 if ( low != temp )
 {
  toSort(head, low, temp->prior);
 }
 if ( high != temp )
 {
  toSort(head, temp->next, high);
 }
}

void quicksort(LNode * head){
    LinkList p,temp;
    p=head->next;
    if(p->next!=NULL)//防止只录入了一个人报错
    temp=p->next;
    else
    return;
    while(temp->next!=NULL){
        if(p->data.time==temp->data.time){//因为打印时是倒序打印,所以这里也需要把学号小的放在后面
            if(p->data.id<temp->data.id){
                exchange(p,temp);
            }
        }
        p=p->next;
        temp=p->next;
    }
    return;
}
//数据交换,难道是因为不是同一结构体???
void exchange(LinkList low,LinkList high){
    unsigned long long ex_id;  char ex_name[20];  char ex_temp0[2];   char ex_major[20];  float ex_time;
	ex_id=low->data.id;strcpy(ex_temp0,low->data.temp0);strcpy(ex_name,low->data.name);strcpy(ex_major,low->data.major);ex_time=low->data.time;
	low->data.id=high->data.id;strcpy(low->data.temp0,high->data.temp0);strcpy(low->data.name,high->data.name);strcpy(low->data.major,high->data.major);low->data.time=high->data.time;
	high->data.id=ex_id;strcpy(high->data.temp0,ex_temp0);strcpy(high->data.name,ex_name);strcpy(high->data.major,ex_major);high->data.time=ex_time;
}
void reply()
{
	char a;
	fflush(stdin);//清空缓冲区以避免读取到先前的回车
	printf("任意键继续");
	if (scanf("%c", &a) == 13)//回车键返回
		return;
	else
		return;//一时间想不到其他任意键返回的写法
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值