数据结构课程设计之学生宿舍信息管理系统

一、问题陈述

宿舍对于大学生在校生活来说相当于家的存在,而宿舍管理又是学校后勤管理的重要环节,如何直观的了解宿舍的入住情况和每位同学的住宿位置是提高工作效率的重要课题,根据我们所学的C语言和数据结构课程中有关链表的内容,为宿舍管理人员编写宿舍管理查询软件,就可以轻松满足实现上述需求。
任务:

  1. 为宿舍管理人员编写一个宿舍管理查询软件, 程序设计要求:
    • 采用交互工作方式
    • 可按关键字(姓名、学号、房号)进行排序
  2. 查询菜单: (用二分查找实现以下操作)
    • 按姓名查询
    • 按学号查询
    • 按房号查询
  3. 打印任一查询结果(可以连续操作)

二、概要设计

2.1 概要简述

根据系统要求,即本系统具有信息的录入,显示,排序显示、查找,插入、删除、结束程序等功能,先设计出详细的系统流程图,然后将源代码输入程序,进行编译调试即可。
程序总体分10个项目:输入记录、显示记录、按姓名排序并显示、按房间号排序并显示 、按学号排序并显示 、按姓名查找并显示 、按房间号查找并显示 、按学号查找并显示、插入一条记录按学号排序并显示以及结束程序。

2.2 线性表存储结构表示
typedef struct {
	char name[20];
	int num;            //学号和房号都为整型
	int room;
} stu;

typedef struct {
	int length; //当前长度
	stu *elem;  //存储空间基址
	int listsize;  //当前分配的存储容量
} linklist;
2.3 详细设计
2.3.1 系统流程图

在这里插入图片描述

2.3.2 三种排序方法及二分查找法
2.3.2.1 冒泡排序(按姓名排序)
//按姓名排序(采用冒泡排序)
void sort1(linklist &L) { 
	int i, j;
	stu temp;
	for (i = 0; i<L.length - 1; i++)
		for (j = 0; j<L.length-1-i; j++)
			if (strcmp(L.elem[j].name, L.elem[j+1].name)>0) {
				temp = L.elem[j];
				L.elem[j] = L.elem[j+1];
				L.elem[j+1] = temp;
			}
}
2.3.2.2 折半插入排序(按学号排序)
//按学号排序(采用折半插入排序)
void sort2(linklist &L) { 
	int i, j, mid, low, high;
	stu temp;
	for (i = 1; i < L.length; i++) {
		if(L.elem[i].num<L.elem[i-1].num) {
			temp = L.elem[i];
			low = 0;
			high = i-1;
			while (low <= high) {
				mid = (low + high) / 2;
				if (temp.num < L.elem[mid].num)
					high = mid - 1;
				else
					low = mid + 1;
			}
			for (j = i - 1; j >= high+1; j--)
				L.elem[j+1]=L.elem[j];
			L.elem[high+1]=temp;
		}
	}
}
2.3.2.3 简单选择排序(按房号排序)
//按房号排序(采用简单选择排序)
void sort3(linklist &L) { 
	int i,j,k;
	stu temp;
	for(i=0; i<L.length-1; i++) {
		k=i;
		for(j=i+1; j<L.length; j++)
			if(L.elem[j].room<L.elem[k].room)
				k=j;
		if(k!=i){
			temp = L.elem[i];
			L.elem[i] = L.elem[k];
			L.elem[k] = temp;
		}
	}
}
2.3.2.4 二分查找法(以按姓名查找为例)
//按姓名从小到大查找(采用二分查找)
void search1(linklist &L) { 
	if (L.length == 0) {
		printf("已无学生记录!\n");
		Ret();
		Menu();
	} else {
		int low = 0, high = L.length, mid, flag = 0;
		printf("\n");
		printf("按姓名查找-->请输入要查找的姓名:");
		char a[15], ch;
		scanf("%s", a);
		while (low <= high) {
			mid = (low + high) / 2;
			if (strcmp(a, L.elem[mid].name) == 0) {
				flag = 1;
				break;
			} else if (strcmp(a, L.elem[mid].name)>0)
				low = mid + 1;
			else
				high = mid - 1;
		}
		if (flag == 1) {
			printf("查找成功-->该学生信息为:\n");
			printf("姓名       学号    房号\n");
			printf("%-10s %-2d %-5d\n", L.elem[mid].name, L.elem[mid].num, L.elem[mid].room);
			if (Select())
				search1(L);
			else {
				system("cls");
				Menu();
			}
		} else {
			printf("该学生不存在!");
			if (Select())    search1(L);
			else {
				system("cls");
				Menu();
			}
		}
	}
}

三、测试与运行

3.1 系统界面

在这里插入图片描述

3.2 新建宿舍名单

在这里插入图片描述

3.3 排序(以姓名排序为例)

在这里插入图片描述

3.4 查询(以学号查询为例)

在这里插入图片描述

3.5 插入学生信息

在这里插入图片描述 在这里插入图片描述

3.6 删除学生信息

在这里插入图片描述 在这里插入图片描述

四、代码实现

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#define N 40 //线性表存储空间的初始分配量
#define increase 10 //线性表存储空间的分配量增量
int choice;  //定义全局变量
typedef struct {
	char name[20];
	int num;            //学号和房号都为整型
	int room;
} stu;
stu stud;
typedef struct {
	int length; //当前长度
	stu *elem;  //存储空间基址
	int listsize;  //当前分配的存储容量
} linklist;

//线性表初始化
void Init(linklist &L) { 
	L.length = 0;
	L.elem = (stu *)malloc(N * sizeof(stu));
	L.listsize = N;
}

//操作菜单
void Menu() { 
	printf( "**************************************\n" );
	printf( "***       欢迎进入宿舍管理系统     ***\n" );
	printf( "**************************************\n" );
	printf( "*        1.  新建宿舍名单            *\n" );
	printf( "*        2.  排序宿舍信息            *\n" );
	printf( "*        3.  查询宿舍信息            *\n" );
	printf( "*        4.  插入宿舍信息            *\n" );
	printf( "*        5.  删除宿舍信息            *\n" );
	printf( "*        0.  退出系统                *\n" );
	printf( "**************************************\n" );
	printf("请输入菜单(0-5):");
	scanf("%d", &choice);
	if (choice<0 || choice>5) {
		system("cls");
		printf("输入数字不对,请重新!\n");
		printf("\n");
		Menu();
	}

}

//打印学生信息
void Display(linklist &L) { 
	int i;
	printf("姓名       学号    房号\n");
	for (i = 0; i<L.length; i++)
		printf("%-10s %-2d %5d\n", L.elem[i].name, L.elem[i].num, L.elem[i].room);
}

//返回主界面
void Ret() {    
	char c;
	fflush(stdin);
	printf("\n");
	printf("请按任意键进入主界面:");
	scanf("%c", &c);
	system("cls");
}

//创建学生信息表
void Create(linklist &L) { 
	if (L.length >= L.listsize) { //判断学生的人数是否超过初值,如果超过,则重新分配
		stu *newbase;
		newbase = (stu*)realloc(L.elem, (N + increase) * sizeof(stu));
		L.elem = newbase;
		L.listsize += increase;
	}
	int i = 2;
	char ch;
	printf("********开始创建学生信息**********\n");
	printf("\n");
	printf("请输入第1个学生的信息\n");
	printf("请输入姓名:");
	fflush(stdin);      // 清空输入缓冲区,得到正确的输入数据
	gets(stud.name);    //输入一行字符串(姓名)
	printf("请输入学号:");
	scanf("%d", &stud.num);
	printf("请输入房号:");
	scanf("%d", &stud.room);
	ch = getchar();
	strcpy(L.elem[L.length].name, stud.name);
	L.elem[L.length].num = stud.num;
	L.elem[L.length].room = stud.room;
	L.length++;
	printf("\n");
	printf("是否继续输入?<y/n>:");
	scanf("%c", &ch);
	printf("\n");
	while (ch == 'y') {
		printf("请输入第%d个学生的信息\n", i);
		printf("请输入姓名:");
		fflush(stdin);      // 清空输入缓冲区,得到正确的输入数据
		gets(stud.name);    //输入一行字符串(姓名)
		printf("请输入学号:");
		scanf("%d", &stud.num);
		printf("请输入房号:");
		scanf("%d", &stud.room);
		strcpy(L.elem[L.length].name, stud.name);
		L.elem[L.length].num = stud.num;
		L.elem[L.length].room = stud.room;
		i++;
		L.length=i-1;
		ch = getchar();
		printf("\n");
		printf("是否继续输入?<y/n>:");
		scanf("%c", &ch);
		printf("\n");
	}
	if (ch == 'n')
		system("cls");
}

//按姓名排序(采用冒泡排序)
void sort1(linklist &L) { 
	int i, j;
	stu temp;
	for (i = 0; i<L.length - 1; i++)
		for (j = 0; j<L.length-1-i; j++)
			if (strcmp(L.elem[j].name, L.elem[j+1].name)>0) {
				temp = L.elem[j];
				L.elem[j] = L.elem[j+1];
				L.elem[j+1] = temp;
			}
}

//按学号排序(采用折半插入排序)
void sort2(linklist &L) { 
	int i, j, mid, low, high;
	stu temp;
	for (i = 1; i < L.length; i++) {
		if(L.elem[i].num<L.elem[i-1].num) {
			temp = L.elem[i];
			low = 0;
			high = i-1;
			while (low <= high) {
				mid = (low + high) / 2;
				if (temp.num < L.elem[mid].num)
					high = mid - 1;
				else
					low = mid + 1;
			}
			for (j = i - 1; j >= high+1; j--)
				L.elem[j+1]=L.elem[j];
			L.elem[high+1]=temp;
		}
	}
}

//按房号排序(采用简单选择排序)
void sort3(linklist &L) { 
	int i,j,k;
	stu temp;
	for(i=0; i<L.length-1; i++) {
		k=i;
		for(j=i+1; j<L.length; j++)
			if(L.elem[j].room<L.elem[k].room)
				k=j;
		if(k!=i){
			temp = L.elem[i];
			L.elem[i] = L.elem[k];
			L.elem[k] = temp;
		}
	}
}
//排序函数
void Sort(linklist &L) { 
	int c;
	printf("请输入排序的方式(1:按名字排序,2:按学号排序,3:按房号排序):");
	scanf("%d", &c);
	switch (c) {
		case 1:
			sort1(L);
			if (L.length == 0) {
				printf("已无学生记录!\n");
				Ret();
				Menu();
			} else {
				printf("按姓名排序:\n");
				Display(L);
				Ret();  //调用返回主界面
				Menu();
			}
			break;
		case 2:
			sort2(L);
			if (L.length == 0) {
				printf("已无学生记录!\n");
				Ret();
				Menu();
			} else {
				printf("按学号排序:\n");
				Display(L);
				Ret();  //调用返回主界面
				Menu();
			}
			break;
		case 3:
			sort3(L);
			if (L.length == 0) {
				printf("已无学生记录!\n");
				Ret();
				Menu();
			} else {
				printf("按房号排序:\n");
				Display(L);
				Ret();  //调用返回主界面
				Menu();
			}
			break;
		default:
			break;
	}
}

//选择是否继续查找
int Select() { 
	char ch;
	scanf("%c", &ch);
	printf("是否继续查找?<y/n>:");
	fflush(stdin);
	scanf("%c", &ch);
	if (ch == 'y') {
		system("cls");
		return 1;
	} else
		return 0;
}

//按姓名从小到大查找(采用二分查找)
void search1(linklist &L) { 
	if (L.length == 0) {
		printf("已无学生记录!\n");
		Ret();
		Menu();
	} else {
		int low = 0, high = L.length, mid, flag = 0;
		printf("\n");
		printf("按姓名查找-->请输入要查找的姓名:");
		char a[15], ch;
		scanf("%s", a);
		while (low <= high) {
			mid = (low + high) / 2;
			if (strcmp(a, L.elem[mid].name) == 0) {
				flag = 1;
				break;
			} else if (strcmp(a, L.elem[mid].name)>0)
				low = mid + 1;
			else
				high = mid - 1;
		}
		if (flag == 1) {
			printf("查找成功-->该学生信息为:\n");
			printf("姓名       学号    房号\n");
			printf("%-10s %-2d %-5d\n", L.elem[mid].name, L.elem[mid].num, L.elem[mid].room);
			if (Select())
				search1(L);
			else {
				system("cls");
				Menu();
			}
		} else {
			printf("该学生不存在!");
			if (Select())    search1(L);
			else {
				system("cls");
				Menu();
			}
		}
	}
}

//按学号从小到大查找(采用二分查找)
void search2(linklist &L) { 
	if (L.length == 0) {
		printf("\n");
		printf("已无学生记录!\n");
		Ret();
		Menu();
	} else {
		int low = 0, high = L.length, mid, flag = 0;
		int n;
		char ch;
		printf("\n");
		printf("按学号查找-->请输入要查找的学号:");
		scanf("%d", &n);
		while (low <= high) {
			mid = (low + high) / 2;
			if (n == L.elem[mid].num) {
				flag = 1;
				break;
			} else if (n>L.elem[mid].num)
				low = mid + 1;
			else
				high = mid - 1;
		}
		if (flag == 1) {
			printf("查找成功----->该学生信息为:\n");
			printf("姓名       学号    房号\n");
			printf("%-1s0 %-2d %-5d\n", L.elem[mid].name, L.elem[mid].num, L.elem[mid].room);
			if (Select())
				search2(L);
			else {
				system("cls");
				Menu();
			}
		} else {
			printf("该学生不存在!");
			if (Select())
				search2(L);
			else {
				system("cls");
				Menu();
			}
		}
	}
}

//按房号从小到大查找(采用二分查找)
void search3(linklist &L) { 
	if (L.length == 0) { //此函数功能为:返回主界面
		printf("\n");
		printf("已无学生记录!\n");
		Ret();
		Menu();
	} else {
		int low = 0, high = L.length, mid, flag = 0;//flag作为标志符,为1则表示查找成功,否则没有所要查找的学生
		int m;
		char ch;
		printf("\n");
		printf("按房号查找-->请输入要查找的房号:");
		scanf("%d", &m);
		while (low <= high) {
			mid = (low + high) / 2;
			if (m == L.elem[mid].room) {
				flag = 1;
				break;
			} else if (m>L.elem[mid].room)
				low = mid + 1;
			else
				high = mid - 1;
		}
		if (flag == 1) {
			printf("查找成功-->该学生信息为:\n");
			printf("姓名       学号    房号\n");
			printf("%-10s %-2d %-5d\n", L.elem[mid].name, L.elem[mid].num, L.elem[mid].room);
			if (Select())    //调用判断函数1
				search3(L);
			else {
				system("cls");
				Menu();
			}
		} else {
			printf("该学生不存在!");
			if (Select())  //调用判断函数2
				search3(L);
			else {
				system("cls");
				Menu();
			}
		}
	}
}

//查找函数
void Search(linklist &L) { 
	int c;
	printf("请输入查找的方式(1:按名字查找,2:按学号查找,3:按房号查找):");
	scanf("%d", &c);
	switch (c) {
		case 1:
			sort1(L);
			search1(L);
			break;//先进行二分查找排序
		case 2:
			sort2(L);
			search2(L);
			break;
		case 3:
			sort3(L);
			search3(L);
			break;
		default:
			break;
	}
}

//按学号从小到大插入该学生
void Insert(linklist &L) { 
	int i, j, k;
	char ch;
	printf("\n");
	printf("插入的学生信息为:\n");
	printf("姓名:");
	fflush(stdin);// 清空输入缓冲区,得到正确的输入数据
	gets(stud.name);
	printf("学号:");
	scanf("%d", &stud.num);
	printf("房号:");
	scanf("%d", &stud.room);
	if (L.length == 0) {
		strcpy(L.elem[L.length].name, stud.name);
		L.elem[L.length].num = stud.num;
		L.elem[L.length].room = stud.room;
	}
	for (i = 0; i<L.length; i++) {
		if (stud.num<L.elem[i].num) {
			k = i;
			for (j = L.length; j>k; j--)
				L.elem[j] = L.elem[j - 1];
			strcpy(L.elem[k].name, stud.name);
			L.elem[k].num = stud.num;
			L.elem[k].room = stud.room;
			break;
		} else {
			strcpy(L.elem[L.length].name, stud.name);
			L.elem[L.length].num = stud.num;
			L.elem[L.length].room = stud.room;
		}
	}
	L.length++;
	fflush(stdin);
	printf("\n");
	printf("是否继续插入?<y/n>:");
	scanf("%c", &ch);
	if (ch == 'y') Insert(L);
	else system("cls");
}

//按学号删除该学生
void Delete(linklist &L) { 
	int i, j, k = -1;
	char ch;
	printf("\n");
	printf("\n");
	printf("请输入要删除学生的学号:");
	scanf("%d", &stud.num);
	for (i = 0; i<L.length; i++) {
		if (stud.num == L.elem[i].num) {
			printf("该学生的信息为:\n");
			printf("姓名:%s \n学号:%d \n房号:%d\n", L.elem[i].name, L.elem[i].num, L.elem[i].room);
			k = i;
			for (j = k; j<L.length - 1; j++)
				L.elem[j] = L.elem[j + 1];
			printf("已成功删除\n");

			break;
		}
	}
	if (i >= L.length) printf("该学生不存在\n");
	if (k >= 0)L.length--;
	fflush(stdin);
	printf("\n");
	printf("是否继续删除操作?<y/n>:");
	scanf("%c", &ch);
	system("cls");
	if (ch == 'y') Delete(L);
	else system("cls");
}

//主函数
int main() {  
	linklist L;    //定义线性表 L
	Init(L);
	Menu();        //调用主菜单函数
	while (choice != 0) {
		system("cls");
		switch (choice) {
			case 1:
				Create(L);    //调用线性表创建函数
				Menu();
				break;
			case 2:
				Sort(L);
				break;//调用排序函数
			case 3:
				Search(L);
				break;//调用查找函数进行(二分)查找
			case 4:
				sort2(L);      //调用学号排序函数
				Insert(L);        //按学号序列插入
				system("cls");
				printf("插入后的学生信息:\n");
				Display(L);
				Ret();
				Menu();
				break;
			case 5:
				Delete(L);    //调用删除函数
				if (L.length == 0) {
					printf("\n");
					printf("学生记录已被删除完!\n");
					Ret();
					Menu();
				} else {
					printf("显示删除后的学生信息:\n");
					Display(L);
					Ret();
					Menu();
				}
				break;
		}
	}
}

  • 90
    点赞
  • 799
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 22
    评论
根据引用[1]提供的信息,宿舍管理系统的ER模型需要进行需求分析、E-R图设计、建库源码等多个步骤。因此,我将为您介绍ER模型设计的一般步骤,以帮助您更好地理解宿舍管理系统ER模型的设计过程。 一般来说,ER模型设计的步骤如下: 1. 需求分析:确定系统的需求和功能,包括数据的输入、输出、处理等。 2. 实体识别:确定系统中的实体,例如学生、宿舍、管理员等。 3. 属性识别:确定每个实体的属性,例如学生的姓名、学号、性别等。 4. 关系识别:确定实体之间的关系,例如学生和宿舍之间的关系是居住。 5. ER图设计:根据实体、属性和关系,设计ER图,包括实体、属性和关系之间的联系。 6. 规范化设计:对ER图进行规范化设计,以消除冗余和不一致性。 根据引用提供的信息,宿舍管理系统的ER模型需要进行需求分析、E-R图设计、建库源码等多个步骤。因此,我将为您介绍ER模型设计的一般步骤,以帮助您更好地理解宿舍管理系统ER模型的设计过程。 在宿舍管理系统中,可能会有以下实体: - 学生 - 宿舍 - 管理员 - 宿舍楼 - 宿舍区域 每个实体都有自己的属性,例如: - 学生:姓名、学号、性别、年级、专业等 - 宿舍:宿舍号、楼层、床位数等 - 管理员:姓名、工号、联系方式等 - 宿舍楼:楼号、楼层数、所属区域等 - 宿舍区域:区域名称、包含的宿舍楼等 实体之间的关系可能包括: 学生和宿舍之间的关系是居住 - 宿舍和宿舍楼之间的关系是所属 - 宿舍楼和宿舍区域之间的关系是所属 根据以上信息,可以设计出宿舍管理系统的ER图,具体如下: ``` 学生 - 居住 - 宿舍 宿舍 - 所属 - 宿舍楼 宿舍楼 - 所属 - 宿舍区域 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tan-1210

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值