宿舍管理查询软件(数据结构与算法课设)(C语言版)

        关于数据结构与算法课程设计--宿舍管理查询软件课题的分享。使用了链表的存储方式和表格的输出打印方式。

目录

1.设计内容和要求

2.代码实现

1.结构体定义

2.新增学生信息

3.删除学生信息

3.查找学生信息

4.排序学生信息

5.显示学生信息

6.菜单函数和主函数

1.设计内容和要求

设计内容和要求(包括原始数据、技术参数、条件、设计要求等):

设计内容:

  1. 输入记录(记录数不少于12条)并建立数据文件,数据文件按关键字(姓名、学号、房号)进行排序(冒泡、选择、插入排序等任选两种),每间房最多6人。
  2. 显示记录;
  3. 查找记录,用二分法实现按姓名、学号、房号查询;
  4. 打印任一查询结果;
  5. 删除记录;
  6. 能够实现连续操作,直至选择退出为止。

设计要求:

   (1)符合课题要求,实现相应功能;

  (2)要求界面友好美观,操作方便易行;

  (3)注意程序的实用性、安全性;

2.代码实现


1.结构体定义

typedef struct student{
	char id[15];
	char name[20];
	char number[20];
	char age[5];
	struct student* next;
} Student;

        使用链表的结构,成员全部使用为char类型,一开始目的是为了方便于输入和进行打印输出,但是在完成整体代码后,对于id和age两个成员还是使用int型比较合适(使用字符型在进行排序时用strcmp比较id,如果位数不统一,没有办法正确排序),这里没有进行更改。

2.新增学生信息

// 辅助函数:计算特定宿舍的学生数量  
int countStu(const char* dormNumber){
	int count = 0;
	Student* current = head;
	while (current != NULL) {
		if (strcmp(current->number, dormNumber) == 0) {
			count++;
		}
		current = current->next;
	}
	return count;
}

void addStudent() {
	Student* newstu = (Student*)malloc(sizeof(Student));

	printf("\033[5m ");
	printf("       新增学生信息\n");
	printf("\033[0m ");
	printf("\n");

	if (newstu == NULL) {
		printf("内存分配失败!\n");
		exit(EXIT_FAILURE);
	}

	// 获取学生信息  
	printf("请输入学生学号(输入格式要统一):");
	scanf("%s", newstu->id); // 注意防止缓冲区溢出  
	printf("请输入学生姓名:");
	scanf("%s", newstu->name);
	char dormNumber[20];
	
	while (1) {
		printf("请输入学生宿舍号:");
		scanf("%s", dormNumber); // 注意防止缓冲区溢出  
			// 确保宿舍不超过6人  
	  if (countStu(dormNumber) < 6) {
		  strcpy(newstu->number, dormNumber); break;
	}
	 else {
		  printf("该宿舍已满,请重新输入宿舍号:\n");
	}
}
	printf("请输入学生年龄:");
	scanf("%s", newstu->age); // 注意限制输入长度  

	// 将新节点添加到链表末尾  
	if (head == NULL) {
		head = newstu;
		newstu->next = NULL;
	}
	else {
		Student* current = head;
		while (current->next != NULL) {
			current = current->next;
		}
		current->next = newstu;
		newstu->next = NULL;
	}

	StuSum++;
	printf("信息插入成功!\n");
}

        对于添加学生信息的函数,链表添加新节点时,加入了一个判断宿舍成员数量的函数(限制一个宿舍住六个人)。

Student* head = NULL;
int StuSum = 0; // 用于跟踪学生总数 

        链表的头节点和表内成员数量StuSum定义为全局变量。

3.删除学生信息

void deleteStudentById() {
 Student* current = head, * prev = NULL;

	if (current == NULL) {
		printf("链表为空,无法删除。\n");
		return;
	}
	char newid[10]; printf("请输入要删除的学生学号\n");
	scanf("%s",newid);

	// 遍历链表以找到具有指定学号的学生  
	while (current != NULL && strcmp(current->id, newid) != 0) {
		prev = current;
		current = current->next;
	}

	if (current == NULL) {
		printf("未找到具有该学号的学生。\n");
		return;
	}

	// 从链表中移除学生  
	if (prev == NULL) {
		// 要删除的是头节点  
		head = current->next;
	}
	else {
		prev->next = current->next;
	}

	free(current); // 释放已删除节点的内存  
	StuSum--; // 更新学生总数  
	printf("学生信息删除成功!\n");
}

         删除操作很常规,判空后遍历链表查找删除。

3.查找学生信息

                                                

int binarySearch_id(Student** stu, int size, const char* target) {
	int low = 0, high = size - 1;
	while (low <= high) {
		int mid = low + (high - low) / 2;
		int cmp = strcmp(stu[mid]->id, target);
		if (cmp == 0) return mid; // 找到目标  
		if (cmp < 0) low = mid + 1;
		else high = mid - 1;
	}
	return -1; // 未找到  
}

void searchStudent_id() {

	Student* current = head;
	char newid[10];
	int s = 0;

	if (current == NULL) {
		printf("链表为空,无信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储信息
	int length = StuSum;

	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
	current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}

	printf("请输入要查询的学生学号:");
	scanf("%s", newid);
	int index = binarySearch_id(Stus, length, newid);

	if (index != -1) {
		current = Stus[index];
		printf("查询成功\n\n");
		printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
		printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
		printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
		displayStudents(current); s++;
		printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n");
	}
	else {
		printf("未找到该学生信息!\n");
	}
	// 释放资源  
	free(Stus);
}
	
	

void searchStudent_name() {

	char newname[15]; int s = 0;
	Student* current = head;
	printf("请输入要查询的学生姓名:");
	scanf("%s",newname);
	while (current != NULL)
	{
		if (strcmp(current->name, newname) == 0) {
			printf("查询成功\n\n");
			printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
			printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
			printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
			displayStudents(current);
			printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n"); s++;
		}
		current = current->next;
	}
	if(s == 0)printf("未找到该学生信息!");
}

void searchStudent_number() {

	char newnumber[15];

	Student* stu = head; 
	printf("请输入要查询的宿舍号:");
	scanf("%s",newnumber);
	int n = countStu(newnumber);
	
	if (n == 0) { printf("未找到该宿舍信息!"); }
	else {
		printf("查询成功\n\n");
		printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
		printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
		printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
		while (stu != NULL) {

			if (strcmp(stu->number, newnumber) == 0) {
				printf("│");
				TablePrint(stu->id, length_1);
				TablePrint(stu->name, length_2);
				TablePrint(stu->number, length_3);
				TablePrint(stu->age, length_4);
				printf("\n");
				stu = stu->next;
				n--;
				if (n == 0) printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n");
				else printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");

			}
		}

	}
}

         在查找信息函数中,课题要求使用二分查找,这里只对按照id查找使用了二分查找(其实另外两种查找方式都可以类比binarySearch_id的写法改善成二分查找的方法)。实现的基本思路还是由链表转化到一个二重指针数组,然后再在数组中进行二分查找。

             

    4.排序学生信息

void sortStudent_id() {
 
	Student* current = head;
	if (current == NULL) {
		printf("链表为空,无信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储信息
	int length = StuSum;
	
	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
		current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}
		// 使用冒泡排序对信息按编号进行排序
	for (int i = 0; i < length - 1; i++) {
		for (int j = 0; j < length - i - 1; j++) {
			if (strcmp(Stus[j]->id, Stus[j + 1]->id) > 0) {
				Student* temp = Stus[j];
				Stus[j] = Stus[j + 1];
				Stus[j + 1] = temp;
			}
		}
	}
		// 更新链表顺序
		head = Stus[0];
		current = head;
		for (int i = 1; i < length; i++) {
			current->next = Stus[i];
			current = current->next;
		}
		current->next = NULL;
		printf("排序完成\n");
		free(Stus);
}


void sortStudent_age(){

	Student* current = head;
	if (current == NULL) {
		printf("链表为空,无信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储信息
	int length = StuSum;

	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
	current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}
	// 使用插入排序对信息按年龄进行排序
	for (int i = 1; i < length; i++) {
		Student* key = Stus[i]; // 当前要插入的元素  
		int j = i - 1;

		// 将Stus[i]插入到Stus[0...i-1]中的正确位置  
		while (j >= 0 && strcmp(Stus[j]->age, key->age) > 0) {
			Stus[j + 1] = Stus[j]; // 元素后移  
			j = j - 1;
		}
		Stus[j + 1] = key; // 插入到正确位置  
	}
	// 更新链表顺序
	head = Stus[0];
	current = head;
	for (int i = 1; i < length; i++) {
		current->next = Stus[i];
		current = current->next;
	}
	current->next = NULL;
	printf("排序完成\n");
	free(Stus);
	
}
void sortStudent_number(){

	Student* current = head;
	if (current == NULL) {
		printf("链表为空,无职工信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储职工信息
	int length = StuSum;

	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
	current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}

	for (int i = 0; i < length - 1; i++) {
		int minIndex = i;
		for (int j = i + 1; j < length; j++) {
			if (strcmp(Stus[j]->number, Stus[minIndex]->number) < 0 ||
				(strcmp(Stus[j]->number, Stus[minIndex]->number) == 0 &&
					strcmp(Stus[j]->id, Stus[minIndex]->id) < 0)) {
				minIndex = j;
			}
		}
		if (minIndex != i) {
			Student* temp = Stus[i];
			Stus[i] = Stus[minIndex];
			Stus[minIndex] = temp;
		}
	}
	// 更新链表顺序
	head = Stus[0];
	current = head;
	for (int i = 1; i < length; i++) {
		current->next = Stus[i];
		current = current->next;
	}
	current->next = NULL;
	printf("排序完成\n");
	free(Stus);

}

        排序是基于三个关键字的三个函数,由于对链表进行排序不是很方便,这里我创建了一个二重指针的数组,把链表转化到数组中,在对数组进行相关排序,最后在由数组转回到链表形式。这里三种排序其实都用到了,冒泡,插入,选择,三个函数各自使用了一种。

5.显示学生信息

void TablePrint(char* date, int length) {
	 
	int padding = (length - strlen(date))/2;
	for (int i = 0; i < padding; i++) { printf(" ");}
	printf("%s", date);
	for (int j = 0; j < (length - strlen(date) - padding); j++) { printf(" ");}
	printf("│");

}

void displayStudents(Student* stu) {
	
	//打印成员信息
	printf("│");
	TablePrint(stu->id,length_1);
	TablePrint(stu->name, length_2);
	TablePrint(stu->number, length_3);
	TablePrint(stu->age, length_4);
	printf("\n");

}

        为了绘制表格,还是需要根据给定的长度来计算空格数量使得数据居中。在这次的输出函数中没有添加表头和数据每行间的分割符,就导致在菜单函数和查找函数中要进行表头的打印和一个是否打印表格结尾行的判断。

6.菜单函数和主函数

void Menu() {
	system("cls");
	printf("******************************\n");
	printf("\033[5m ");
	printf("*       宿舍管理系统         *\n");
	printf("\033[0m ");
	printf("\n");
	printf("*     1. 添加学生信息        *\n");
	printf("*     2. 显示所有信息        *\n");
	printf("*     3. 查询学生信息        *\n");
	printf("*     4. 排序学生信息        *\n");
	printf("*     5. 删除学生信息        *\n");
	printf("*       0. 退出系统          *\n");
	printf("******************************\n");
}
void Menuport(){
	
	printf("请输入您的选择:");
	int choice; 
	while (1) {
		
		scanf("%d", &choice);
		switch (choice) {
		case 1:
			Menu(); addStudent(); printf("请输入您的选择:");
			break;

		case 2: {
			Menu();
			printf("\033[5m ");
			printf("       学生信息显示\n");
			printf("\033[0m ");
			printf("\n");
			//打印表头
			printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
			printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
			printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
			student* h = head;
			while (h != NULL) {
				displayStudents(h);
				if (h->next == NULL) {
					printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n");
				}
				else {
					printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
					
				}
					h = h->next;
			}
			printf("请输入您的选择:");

			break;
		}
		case 3:
			Menu();
			printf("\033[5m ");
			printf("       学生信息查找\n");
			printf("\033[0m ");
			printf("\n");
			int input1;
			printf("***********************\n");
			printf("*    请选择查找方法   *\n");
			printf("*                     *\n");
			printf("*   1.按照学号查找    *\n");
			printf("*   2.按照宿舍查找    *\n");
			printf("*   3.按照姓名查找    *\n");
			printf("*     0.退出查找      *\n");
			printf("*                     *\n");
			
			while (1) {
				printf("***********************\n");
				printf("查找:请选择您的操作:");
				scanf("%d", &input1);
				if (input1 == 0) { printf("已退出查找\n"); break; }
				else if (input1 == 1) { searchStudent_id(); }
				else if (input1 == 2) { searchStudent_number();}
				else if (input1 == 3) { searchStudent_name(); }
				else {printf("输入错误,已退出查找\n"); break;}
			}
			printf("请输入您的选择:");
			break;
		
		case 4:
			Menu();
			printf("\033[5m ");
			printf("       学生信息排序\n");
			printf("\033[0m ");
			printf("\n");
			int input2;
			printf("***********************\n");
			printf("*    请选择排序方法   * \n");
			printf("*                     *\n");
			printf("*   1.按照学号排序    * \n");
			printf("*   2.按照宿舍排序    *\n");
			printf("*   3.按照年龄排序    *\n");
			printf("*                     * \n");
			printf("***********************\n");
			scanf("%d", &input2);
			switch (input2) {
			case 1:sortStudent_id(); break;
			case 2:sortStudent_number(); break;
			case 3:sortStudent_age(); break;
			default:printf("输入错误,已退出排序\n");
			}printf("请输入您的选择:");
			break;
		
		case 5:
			Menu();
			printf("\033[5m ");
			printf("       学生信息删除\n");
			printf("\033[0m ");
			printf("\n");
			deleteStudentById(); printf("请输入您的选择:");
			break;

		case 0:
			exit(-3);

		default:
			Menu(); printf("输入错误,请重新输入!");
		}
	}
}
int main() {
	Menu();
	Menuport();
	return 0;
}

            这里没有另外查找和排序的小菜单,直接在case中再插入switch或者if判断,这里出现过一点问题:case 2 一开始没有加{ },导致新命名Student *h = head 时会一直报错,这里就要注意在Switch和case语句里虽然没有{ }并不会报错,但是为了编码规范,建议添加,避免出现这样的问题。

*7.完整代码

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define length_1 15
#define length_2 20
#define length_3 16
#define length_4 16

typedef struct student{
	char id[15];
	char name[20];
	char number[20];
	char age[5];
	struct student* next;
} Student;

Student* head = NULL;
int StuSum = 0; // 用于跟踪学生总数  
int n = StuSum;

// 辅助函数:计算特定宿舍的学生数量  
int countStu(const char* dormNumber){
	int count = 0;
	Student* current = head;
	while (current != NULL) {
		if (strcmp(current->number, dormNumber) == 0) {
			count++;
		}
		current = current->next;
	}
	return count;
}

void addStudent() {
	Student* newstu = (Student*)malloc(sizeof(Student));

	printf("\033[5m ");
	printf("       新增学生信息\n");
	printf("\033[0m ");
	printf("\n");

	if (newstu == NULL) {
		printf("内存分配失败!\n");
		exit(EXIT_FAILURE);
	}

	// 获取学生信息  
	printf("请输入学生学号(输入格式要统一):");
	scanf("%s", newstu->id); // 注意防止缓冲区溢出  
	printf("请输入学生姓名:");
	scanf("%s", newstu->name);
	char dormNumber[20];
	
	while (1) {
		printf("请输入学生宿舍号:");
		scanf("%s", dormNumber); // 注意防止缓冲区溢出  
			// 确保宿舍不超过6人  
	  if (countStu(dormNumber) < 6) {
		  strcpy(newstu->number, dormNumber); break;
	}
	 else {
		  printf("该宿舍已满,请重新输入宿舍号:\n");
	}
}
	printf("请输入学生年龄:");
	scanf("%s", newstu->age); // 注意限制输入长度  

	// 将新节点添加到链表末尾  
	if (head == NULL) {
		head = newstu;
		newstu->next = NULL;
	}
	else {
		Student* current = head;
		while (current->next != NULL) {
			current = current->next;
		}
		current->next = newstu;
		newstu->next = NULL;
	}

	StuSum++;
	printf("信息插入成功!\n");
}

void TablePrint(char* date, int length) {
	 
	int padding = (length - strlen(date))/2;
	for (int i = 0; i < padding; i++) { printf(" ");}
	printf("%s", date);
	for (int j = 0; j < (length - strlen(date) - padding); j++) { printf(" ");}
	printf("│");

}

void displayStudents(Student* stu) {
	
	//打印成员信息
	printf("│");
	TablePrint(stu->id,length_1);
	TablePrint(stu->name, length_2);
	TablePrint(stu->number, length_3);
	TablePrint(stu->age, length_4);
	printf("\n");

}

int binarySearch_id(Student** stu, int size, const char* target) {
	int low = 0, high = size - 1;
	while (low <= high) {
		int mid = low + (high - low) / 2;
		int cmp = strcmp(stu[mid]->id, target);
		if (cmp == 0) return mid; // 找到目标  
		if (cmp < 0) low = mid + 1;
		else high = mid - 1;
	}
	return -1; // 未找到  
}

void searchStudent_id() {

	Student* current = head;
	char newid[10];
	int s = 0;

	if (current == NULL) {
		printf("链表为空,无信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储信息
	int length = StuSum;

	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
	current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}

	printf("请输入要查询的学生学号:");
	scanf("%s", newid);
	int index = binarySearch_id(Stus, length, newid);

	if (index != -1) {
		current = Stus[index];
		printf("查询成功\n\n");
		printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
		printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
		printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
		displayStudents(current); s++;
		printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n");
	}
	else {
		printf("未找到该学生信息!\n");
	}
	// 释放资源  
	free(Stus);
}
	
	

void searchStudent_name() {

	char newname[15]; int s = 0;
	Student* current = head;
	printf("请输入要查询的学生姓名:");
	scanf("%s",newname);
	while (current != NULL)
	{
		if (strcmp(current->name, newname) == 0) {
			printf("查询成功\n\n");
			printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
			printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
			printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
			displayStudents(current);
			printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n"); s++;
		}
		current = current->next;
	}
	if(s == 0)printf("未找到该学生信息!");
}

void searchStudent_number() {

	char newnumber[15];

	Student* stu = head; 
	printf("请输入要查询的宿舍号:");
	scanf("%s",newnumber);
	int n = countStu(newnumber);
	
	if (n == 0) { printf("未找到该宿舍信息!"); }
	else {
		printf("查询成功\n\n");
		printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
		printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
		printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
		while (stu != NULL) {

			if (strcmp(stu->number, newnumber) == 0) {
				printf("│");
				TablePrint(stu->id, length_1);
				TablePrint(stu->name, length_2);
				TablePrint(stu->number, length_3);
				TablePrint(stu->age, length_4);
				printf("\n");
				stu = stu->next;
				n--;
				if (n == 0) printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n");
				else printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");

			}
		}

	}
}


void deleteStudentById() {
 Student* current = head, * prev = NULL;

	if (current == NULL) {
		printf("链表为空,无法删除。\n");
		return;
	}
	char newid[10]; printf("请输入要删除的学生学号\n");
	scanf("%s",newid);

	// 遍历链表以找到具有指定学号的学生  
	while (current != NULL && strcmp(current->id, newid) != 0) {
		prev = current;
		current = current->next;
	}

	if (current == NULL) {
		printf("未找到具有该学号的学生。\n");
		return;
	}

	// 从链表中移除学生  
	if (prev == NULL) {
		// 要删除的是头节点  
		head = current->next;
	}
	else {
		prev->next = current->next;
	}

	free(current); // 释放已删除节点的内存  
	StuSum--; // 更新学生总数  
	printf("学生信息删除成功!\n");
}

void sortStudent_id() {
 
	Student* current = head;
	if (current == NULL) {
		printf("链表为空,无信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储信息
	int length = StuSum;
	
	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
		current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}
		// 使用冒泡排序对信息按编号进行排序
	for (int i = 0; i < length - 1; i++) {
		for (int j = 0; j < length - i - 1; j++) {
			if (strcmp(Stus[j]->id, Stus[j + 1]->id) > 0) {
				Student* temp = Stus[j];
				Stus[j] = Stus[j + 1];
				Stus[j + 1] = temp;
			}
		}
	}
		// 更新链表顺序
		head = Stus[0];
		current = head;
		for (int i = 1; i < length; i++) {
			current->next = Stus[i];
			current = current->next;
		}
		current->next = NULL;
		printf("排序完成\n");
		free(Stus);
}


void sortStudent_age(){

	Student* current = head;
	if (current == NULL) {
		printf("链表为空,无信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储信息
	int length = StuSum;

	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
	current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}
	// 使用插入排序对信息按年龄进行排序
	for (int i = 1; i < length; i++) {
		Student* key = Stus[i]; // 当前要插入的元素  
		int j = i - 1;

		// 将Stus[i]插入到Stus[0...i-1]中的正确位置  
		while (j >= 0 && strcmp(Stus[j]->age, key->age) > 0) {
			Stus[j + 1] = Stus[j]; // 元素后移  
			j = j - 1;
		}
		Stus[j + 1] = key; // 插入到正确位置  
	}
	// 更新链表顺序
	head = Stus[0];
	current = head;
	for (int i = 1; i < length; i++) {
		current->next = Stus[i];
		current = current->next;
	}
	current->next = NULL;
	printf("排序完成\n");
	free(Stus);
	
}
void sortStudent_number(){

	Student* current = head;
	if (current == NULL) {
		printf("链表为空,无职工信息!\a\n");
		return;
	}
	// 创建一个临时数组,用于存储职工信息
	int length = StuSum;

	Student** Stus = (Student**)malloc(sizeof(Student*) * length);
	if (Stus == NULL) {
		printf("内存分配失败,程序意外退出!\a\n");
		exit(1);
	}
	current = head;
	for (int i = 0; i < length; i++) {
		Stus[i] = current;
		current = current->next;
	}

	for (int i = 0; i < length - 1; i++) {
		int minIndex = i;
		for (int j = i + 1; j < length; j++) {
			if (strcmp(Stus[j]->number, Stus[minIndex]->number) < 0 ||
				(strcmp(Stus[j]->number, Stus[minIndex]->number) == 0 &&
					strcmp(Stus[j]->id, Stus[minIndex]->id) < 0)) {
				minIndex = j;
			}
		}
		if (minIndex != i) {
			Student* temp = Stus[i];
			Stus[i] = Stus[minIndex];
			Stus[minIndex] = temp;
		}
	}
	// 更新链表顺序
	head = Stus[0];
	current = head;
	for (int i = 1; i < length; i++) {
		current->next = Stus[i];
		current = current->next;
	}
	current->next = NULL;
	printf("排序完成\n");
	free(Stus);

}

void Menu() {
	system("cls");
	printf("******************************\n");
	printf("\033[5m ");
	printf("*       宿舍管理系统         *\n");
	printf("\033[0m ");
	printf("\n");
	printf("*     1. 添加学生信息        *\n");
	printf("*     2. 显示所有信息        *\n");
	printf("*     3. 查询学生信息        *\n");
	printf("*     4. 排序学生信息        *\n");
	printf("*     5. 删除学生信息        *\n");
	printf("*       0. 退出系统          *\n");
	printf("******************************\n");
}
void Menuport(){
	
	printf("请输入您的选择:");
	int choice; 
	while (1) {
		
		scanf("%d", &choice);
		switch (choice) {
		case 1:
			Menu(); addStudent(); printf("请输入您的选择:");
			break;

		case 2: {
			Menu();
			printf("\033[5m ");
			printf("       学生信息显示\n");
			printf("\033[0m ");
			printf("\n");
			//打印表头
			printf("┌───────────────┬────────────────────┬────────────────┬────────────────┐\n");
			printf("│      学号     │        姓名        │     宿舍号     │      年龄      │\n");
			printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
			student* h = head;
			while (h != NULL) {
				displayStudents(h);
				if (h->next == NULL) {
					printf("└───────────────┴────────────────────┴────────────────┴────────────────┘\n");
				}
				else {
					printf("├───────────────┼────────────────────┼────────────────┼────────────────┤\n");
					
				}
					h = h->next;
			}
			printf("请输入您的选择:");

			break;
		}
		case 3:
			Menu();
			printf("\033[5m ");
			printf("       学生信息查找\n");
			printf("\033[0m ");
			printf("\n");
			int input1;
			printf("***********************\n");
			printf("*    请选择查找方法   *\n");
			printf("*                     *\n");
			printf("*   1.按照学号查找    *\n");
			printf("*   2.按照宿舍查找    *\n");
			printf("*   3.按照姓名查找    *\n");
			printf("*     0.退出查找      *\n");
			printf("*                     *\n");
			
			while (1) {
				printf("***********************\n");
				printf("查找:请选择您的操作:");
				scanf("%d", &input1);
				if (input1 == 0) { printf("已退出查找\n"); break; }
				else if (input1 == 1) { searchStudent_id(); }
				else if (input1 == 2) { searchStudent_number();}
				else if (input1 == 3) { searchStudent_name(); }
				else {printf("输入错误,已退出查找\n"); break;}
			}
			printf("请输入您的选择:");
			break;
		
		case 4:
			Menu();
			printf("\033[5m ");
			printf("       学生信息排序\n");
			printf("\033[0m ");
			printf("\n");
			int input2;
			printf("***********************\n");
			printf("*    请选择排序方法   * \n");
			printf("*                     *\n");
			printf("*   1.按照学号排序    * \n");
			printf("*   2.按照宿舍排序    *\n");
			printf("*   3.按照年龄排序    *\n");
			printf("*                     * \n");
			printf("***********************\n");
			scanf("%d", &input2);
			switch (input2) {
			case 1:sortStudent_id(); break;
			case 2:sortStudent_number(); break;
			case 3:sortStudent_age(); break;
			default:printf("输入错误,已退出排序\n");
			}printf("请输入您的选择:");
			break;
		
		case 5:
			Menu();
			printf("\033[5m ");
			printf("       学生信息删除\n");
			printf("\033[0m ");
			printf("\n");
			deleteStudentById(); printf("请输入您的选择:");
			break;

		case 0:
			exit(-3);

		default:
			Menu(); printf("输入错误,请重新输入!");
		}
	}
}
int main() {
	Menu();
	Menuport();
	return 0;
}

        有问题欢迎大家在评论区和私信批评指正。

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值