目录
功能展示
界面展示
所有功能模块:
功能1:菜单模块(显示功能菜单)
功能2:增加学生信息
功能3:输出学生信息(查看所有学习信息)
功能4:修改学生信息
功能5:删除学生信息
功能6:查询单个学生信息
功能7:排序学习信息(按照学号升序排序)
功能8:退出管理系统
心得分享
过程梳理
个人总结
学生管理系统(完整代码)
main.cpp
student.h
student.cpp
第一步:修改信息
第二步:查询验证
第一步:删除信息
第一步:查询验证
在排序之前,先增加几条数据:
执行排序:
验证结果(该数据无法验证是否执行头排序)
再插入一条比第一条小的数据(用于执行头排序):
执行(头)排序:
验证结果:
过程梳理
- 首先要根据需求分析,将各个功能模块罗列出来
- 数据建模,对数据进行封装,创建一个student结构体,添加我们需要的各种数据。
- 创建一个可以循环输入命令的菜单,并且可以退出,还可以检查输入的指令是否匹配。
- 然后一个个功能模块实现就可以了。但要注意实现功能的顺序。(写功能也要有顺序,这样可以事半功倍)
- 第一个功能,肯定就是添加了,每当需要添加的时候,就需要申请一块内存,创建一个student结构体,并赋予相应的数据。
- 第二个功能,就是打印全部数据。
- 第三个功能,实现单个数据的查询。
- 第四个功能,实现单个数据的删除。(删除和修改都差不多)
- 第五个功能,实现单个数据的修改。
- 第六个功能,也就是最难的功能——链表排序
- 最后,对细节进行处理。
个人总结
- 当思维混乱的时候,不妨画图来理解。
- 写循环时,一定要明确跳出的逻辑和循环的次数和迭代方法。
- 在实现功能的时候,还需要考虑特殊情况!边界条件的处理尤其重要。(在排序的时候,一定要考虑多个因素)
- 总体难度不大,但是需要一步一步去实现,更多的是考验对细节的处理,后面又看了别人的实现方法,发现自己的思维方式还是比较呆板,别人几行就可以搞定的,自己还是用了各种if分支和for循环才搞定,还得加强自己的思维能力,多刷算法!
# include "student.h"
int main(){
StudentNode* s = NULL;
int command;
while (true)
{
myMenu(); // 展示菜单
scanf("%d", &command); // 输入
switch (command)
{
case 1:// 增加学生信息
AddStudent(&s);
break;
case 2:// 删除学生信息
DeleteStudent(&s);
break;
case 3:// 修改学生信息
UpdateStudent(&s);
break;
case 4:// 查询学生信息 (可按照姓名和学号)
SearchStudent(&s);
break;
case 5:// 输出学生信息 (打印所有学生信息)
MyPrint(s);
break;
case 6:// 排序学生信息 (按照学号升序排序)
MySort(&s);
break;
case 0:// 退出管理系统
exit();
break;
default : //输入有误
error();
break;
}
system("pause");
}
}
#pragma once
#include
#include
#include
typedef int STDateTypeOne;
typedef char STDateTypeTow;
// 学生
typedef struct StudentNode
{
int ID; // 学号
int Score; // 排名
char Name[50]; // 姓名
char Sex[10]; // 性别
char Profession[50]; // 专业
char Phone[20]; // 电话号码
char Q[20]; // QQ号
struct StudentNode* next; // 指针域
}StudentNode;
// 主菜单界面
void myMenu();
// 退出系统
void exit();
// 命令有误
void error();
// ----------------------------------CRUD模块
void AddStudent(StudentNode** s); // 添加
void DeleteStudent(StudentNode** s); // 删除
void UpdateStudent(StudentNode** s); // 更新
void SearchStudent(StudentNode** s); // 查询
// ----------------------------------其他模块
void MyPrint(StudentNode* s); // 输出学生信息 (打印所有学生信息)
void MySort(StudentNode** s); // 排序学生信息 (按照学号升序排序)
#include "student.h"
// 字符判断
int MyStrcmp(const char* str1, const char* str2)
{
assert(NULL != str1);
assert(NULL != str2);//防御性编程
while (*(unsigned char*)str1 == *(unsigned char*)str2)
{
if (*(unsigned char*)str1 != '\0')
{
return 0;//当*(unsigned char*)str1 ==*(unsigned char*)str2==‘\0'时两个字符串完全相等
}
str1++; //比较下个字符
str2++;
}
//*(unsigned char*)str1 与*(unsigned char*)str2的差值与返回值正负匹配
return *(unsigned char*)str1 - *(unsigned char*)str2;
}
// 菜单
void myMenu(){
system("cls");
printf("****************************************************************\n");
printf("*********** \033[34m学生信息管理系统 \033[30m ***********\n");
printf("----------------------------------------------------------------\n");
printf("*********** \033[32m 1 \033[30m---- 增加学生信息 ***********\n");
printf("*********** \033[32m 2 \033[30m---- 删除学生信息 ***********\n");
printf("*********** \033[32m 3 \033[30m---- 修改学生信息 ***********\n");
printf("*********** \033[32m 4 \033[30m---- 查询学生信息 ***********\n");
printf("*********** \033[32m 5 \033[30m---- 输出学生信息 ***********\n");
printf("*********** \033[32m 6 \033[30m---- 排序学生信息 ***********\n");
printf("*********** \033[32m 0 \033[30m---- 退出管理系统 ***********\n");
printf("****************************************************************\n");
printf("\033[31m");
printf("请选择想要实现的功能(数字):");
}
// 退出管理系统
void exit()
{
system("cls");
printf("欢迎下次使用学生信息管理系统!\n");
exit(0); // 结束程序
}
// 提示输入错误
void error(){
printf("请输入对应指令!\n");
}
// ----------------------------------CRUD模块
void AddStudent(StudentNode** s){
int ID; // 学号
int Score; // 排名
char Name[50]; // 姓名
char Sex[10]; // 性别
char Profession[50]; // 专业
char Phone[20]; // 电话号码
char Q[20]; // QQ号
// 创建新节点
StudentNode* newnode = (StudentNode*)malloc(sizeof(StudentNode)); //将申请的空间---强转为 指针变量
// 输入数据
printf("请输入新增学生的相关信息:\n");
printf("学号:");
scanf("%d", &newnode->ID); // 输入
printf("排名:");
scanf("%d", &newnode->Score); // 输入
printf("姓名:");
scanf("%s", &newnode->Name); // 输入
printf("性别: ");
scanf("%s", &newnode->Sex); // 输入
printf("专业: ");
scanf("%s", &newnode->Profession); // 输入
printf("电话号码:");
scanf("%s", &newnode->Phone); // 输入
printf("QQ号: ");
scanf("%s", &newnode->Q); // 输入
newnode->next = NULL;
// 尾插
if(*s == NULL){
*s = newnode;
}
else{
printf("添加中...\n");
//找到尾节点
StudentNode* tp = *s;
StudentNode* tmp;
while(tp->next != NULL){
tmp = tp->next;
tp = tmp;
}
tp->next = newnode;
}
printf("添加成功!\n");
}
void DeleteStudent(StudentNode** s){
//判断链表是不是空
if(*s == NULL){
printf("当前还没有任何数据!\n ");
return;
}
// 展示所以数据
MyPrint(*s);
int id;
// 选择删除的数据
printf("您要删除第几条信息: ");
scanf("%d", &id); // 输入
// 进行删除
StudentNode* tp = *s;
StudentNode* flag= *s;
// 删头节点
if(id == 1){
StudentNode* p = (*s)->next;
free(*s);
*s = p;
printf("删除成功!\n");
return;
}
for(int i = 1; i< id; i++){
flag = tp;
tp = tp->next;
}
flag->next = tp->next;
free(tp);
printf("删除成功!\n");
}
void UpdateStudent(StudentNode** s){
//判断链表是不是空
if(*s == NULL){
printf("当前还没有任何数据!\n ");
return;
}
// 展示所以数据
MyPrint(*s);
int id;
// 选择修改的信息
printf("您要修改第几条信息: ");
scanf("%d", &id); // 输入
// 进行修改
StudentNode* tp = *s;
StudentNode* flag= *s;
for(int i = 1; i< id; i++){
tp = tp->next;
}
// 请输入您要修改的数据
printf("请输入您要修改的数据 :\n");
printf("学号:");
scanf("%d", &tp->ID); // 输入
printf("排名:");
scanf("%d", &tp->Score); // 输入
printf("姓名:");
scanf("%s", &tp->Name); // 输入
printf("性别: ");
scanf("%s", &tp->Sex); // 输入
printf("专业: ");
scanf("%s", &tp->Profession); // 输入
printf("电话号码:");
scanf("%s", &tp->Phone); // 输入
printf("QQ号: ");
scanf("%s", &tp->Q); // 输入
// 修改成功!
printf("修改成功! \n");
}
void SearchStudent(StudentNode** s){
//判断链表是不是空
if(*s == NULL){
printf("当前还没有任何数据!\n ");
return;
}
StudentNode* p = *s;
int choice;
int myid; // 学号
char myname[50]; // 姓名
// 选择查询方法
printf("请选择查询方式(0:学号 / 1:姓名) : ");
scanf("%d", &choice); // 输入
// 学号查询
if(choice == 0){
printf("请输入查询的学号 : ");
scanf("%d", &myid); // 输入
while(1){
// 边界判断
if(p->next == NULL){
if(p->ID == myid){
printf("__________________________________________");
printf("_______________________________________\n");
printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
}else{
printf("您所查找的学生不存在!\n");
}
break;
}
// 判断学号
if(p->ID == myid){
printf("__________________________________________");
printf("_______________________________________\n");
printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
break;
}
// 继续遍历
p = p->next;
}
return;
}
if(choice == 1){
printf("请输入查询的姓名 : ");
scanf("%s", &myname); // 输入
while(1){
// 边界判断
if(p->next == NULL){
// 判断姓名
int i = MyStrcmp(p->Name, myname);
if(i == 0){
printf("|学号\t|排名\t|姓名\t|性别\t|专业\t\t|电话\t\t|QQ\t\t|\n");
printf("__________________________________________");
printf("_______________________________________\n");
printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
break;
}
else{
printf("您所查找的学生不存在!\n");
}
break;
}
// 判断姓名
int i = MyStrcmp(p->Name, myname);
if(i == 0){
printf("|学号\t|排名\t|姓名\t|性别\t|专业\t\t|电话\t\t|QQ\t\t|\n");
printf("__________________________________________");
printf("_______________________________________\n");
printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
break;
}
// 继续遍历
p = p->next;
}
return;
}
printf("请输入正常的指令!\n");
}
// ----------------------------------其他模块
void MyPrint(StudentNode* s){
system("cls");
StudentNode* p = s;
if(!p){
printf("暂无任何信息!\n");
return;
}
printf("|学号\t|排名\t|姓名\t|性别\t|专业\t\t|电话\t\t|QQ\t\t|\n");
while (p != NULL)
{
printf("__________________________________________");
printf("_______________________________________\n");
printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
p = p->next;
}
}
//=============冒泡排序====================升序
void MySort(StudentNode** s){
StudentNode* p = *s;
StudentNode* temp;
int lenth = 0;
// 判断特殊情况 长度为1
if((p -> next == NULL))
{
printf("长度为1,无需排序!\n");
return;
}
// 判断特殊情况 长度为2
if((p -> next -> next == NULL))
{
if(p->ID < p->next->ID){
temp = p; // 保存头节点
*s = (*s)->next; // 头节点换为下一个节点
(*s)->next = temp;
(*s)->next->next = NULL;
}
printf("排序完成! \n");
return;
}
// 获取长度
while(1) {
lenth++;
if(p->next == NULL){
// 退出
break;
}
p = p->next;
}
printf("长度为%d !\n", lenth);
// 冒泡排序
StudentNode* head = *s;
StudentNode* pre = *s; // 当前
StudentNode* cur = (*s)->next; // 当前 +1
StudentNode* next = (*s)->next->next; // 当前 + 2
StudentNode* end = NULL;
for (int i = lenth; i >= 0; i--) {
pre = head;
cur = pre->next;
next = cur->next;
while(next != NULL) {
if (cur->ID > next->ID) {
cur->next = next->next;
pre->next = next;
next->next = cur;
next = cur->next;
pre = pre->next;
}
else {
pre = pre->next;
cur = cur->next;
next = next->next;
}
}
}
// 头结点 排序
head = *s;
cur = *s; // 当前
// cur到尾巴
while(cur->next != NULL){
// 大于上一个,小于下一个
if(head->ID > cur->ID && head->ID < cur->next->ID ){
// 头节点换为下一个节点
*s = (*s)->next;
// 插入 head
temp = cur->next;
cur->next = head;
head->next = temp;
printf("头排序完成!\n");
printf("排序完成!\n");
return;
}
cur = cur->next; // 往下走
}
// 单独比较尾巴
if(head->ID > cur->ID){
// 头节点换为下一个节点
*s = (*s)->next;
cur->next = head;
head->next = NULL;
printf("头排序完成!\n");
}
printf("排序完成!\n");
}