另外之前我也以为这个很难写,写完后的才知道这其实就是顺序表和排序的结合实现,只是额外增加了一点人机交互的一些输入输出而已,其实它很简单就可以实现.(耗时一下午左右就可完成)
0.首先我们需要定义顺序表
typedef struct Student { char id[18]; char name[18]; int grade; }Student;//学生结构体类型重命名 typedef struct SeqList { Student* student;//动态数组,方便后续扩容 int size; int capacity; }SeqList;//顺序表结构体类型重命名
你可以看成是顺序表这个盒子里面装着学生这个盒子的嵌套,盒子里面装着数组长度,学号之类的信息
1.我们再在主函数里定义一个顺序表结构体变量,并调用初始化顺序表初始化接口 函数
SeqList ST; SeqListInit(&ST);//调用顺序表初始化接口函数
void SeqListInit(SeqList* ps) { ps->student = (Student*)malloc(sizeof(Student)*4);//注意这里的是学生结构体类型,可以联想为int类型 if (ps->student == NULL) { printf("malloc fail\n"); exit(-1); } ps->size = 0; ps->capacity = 4;//先给它分配4个Student结构体类型内存大小空间容量 }
2.为了更好的实现人机交互,这里我们用到打印菜单来方便用户选择
void meau() { printf("************************\n"); printf("***** 0.退出程序 *****\n"); printf("*****1.录入学生信息*****\n"); printf("*****2.打印学生信息*****\n"); printf("*****3.插入学生信息*****\n"); printf("*****4.统计学生个数*****\n"); printf("*****5.按姓名来排序*****\n"); printf("*****6.按学号来排序*****\n"); printf("*****7.查找学生信息*****\n"); printf("*****8.删除学生信息*****\n"); }
打印出来就是这样的啦,不是很酷!
3.主函数内的主要轮廓(有了轮廓之后就可以一步步实现这个代码,不要着急
do//先执行一次 { int input = 0; printf("请输入你的选择:>"); scanf("%d", &input); switch (input) { case 0: printf("退出程序\n"); printf("\n");//为了打印界面更美观,所以换行 break;//勿漏 case 1: printf("录入学生信息\n"); printf("\n"); break; case 2: printf("打印学生信息\n"); SeqListPrint(&ST);//调用打印函数接口 printf("\n"); break; case 3: printf("插入学生信息\n"); printf("\n"); break; case 4: printf("统计学生个数\n"); printf("\n"); break; case 5: printf("按姓名来排序\n"); printf("\n"); break; case 6: printf("按学号来排序\n"); printf("\n"); break; case 7: printf("查找学生信息\n"); printf("\n"); break; case 8: printf("删除学生信息\n"); printf("\n"); break; default : printf("输入有误,请重新输入\n"); printf("\n"); break; } } while (input);//当输入0时为假后退出
4.接下来我们就分模块化拆解代码,建议写一模块代码就测试一下,便于找BUG
4-0退出程序代码
case 0: printf("退出程序\n"); printf("\n"); break;
4-1录入学生信息代码
//主函数代码: case 1: printf("录入学生信息\n"); int n = 0; printf("请输入待插入学生的个数;>"); scanf("%d", &n); for (int i = 0; i < n; i++) { Student stu; printf("请输入待插入学生的学号,姓名,分数:>"); scanf("%s%s%d", stu.id, stu.name, &stu.grade);//字符数组输入时不需要& SeqListPushBack(&ST, stu);//调用尾插建立顺序表的接口函数 } printf("插入成功\n"); printf("\n"); break;
尾插建立顺序表的接口函数(和顺序表那里讲的一模一样)
void CheckCapacity(SeqList* ps)//检查是否需要扩容函数 { if (ps->size == ps->capacity) { int newcapacity = 2 * ps->capacity; Student* temp = realloc(ps->student, sizeof(Student) * newcapacity); assert(!temp); ps->student = temp; ps->capacity = newcapacity; } } void SeqListPushBack(SeqList* ps, Student stu)//尾插建立顺序表 { CheckCapacity(ps);//调用检查是否需要扩容函数接口 ps->student[ps->size] = stu; ps->size++;//勿漏 }
4-2打印学生信息代码
case 2: printf("打印学生信息\n"); SeqListPrint(&ST);//调用打印函数接口 printf("\n"); break;
对应函数接口:
void SeqListPrint(SeqList* ps) { for (int i = 0; i < ps->size; i++) { printf("学号:%s\t名字:%s\t分数:%d\n", ps->student[i].id, ps->student[i].name, ps->student[i].grade); } }
4-3指定位置插入学生信息代码:(题目要求使用指定的任意位置插入)
case 3: printf("插入学生信息\n"); //插入学生的位置 int pos = 0; printf("请输入你要待插入学生信息的位置(目前可插入位置必须小于等于%d):>", ST.size); scanf("%d", &pos); //待插入学生的信息 Student stu; printf("请输入待插入学生的学号,姓名,分数:>"); scanf("%s%s%d", stu.id, stu.name, &stu.grade);//装配好学生结构体类型,后续传参 SeqListInsert(&ST, stu, pos - 1);//调用顺序表任意位置插入函数接口 printf("插入成功\n"); printf("\n"); break;
函数接口:
void SeqListInsert(SeqList* ps, Student stu, int pos)//注意传入参数的类型 { CheckCapacity(ps);//调用检查是否需要扩容的函数接口 int end = ps->size - 1; while (end >= pos) { ps->student[end + 1] = ps->student[end];//注意从后面那端开始后移 end--; } ps->student[pos] = stu; ps->size++;//勿漏 } //总结:往哪一端移动就从哪一端开始移动
4-4统计学生个数
case 4: printf("统计学生个数\n"); int sz = SeqListSize(&ST);//调用函数接口并返回值用sz接收 printf("当前统计表中学生的个数为:%d\n", sz); printf("\n"); break;
函数接口:
1. int SeqListSize(SeqList* ps) 2. { 3. return ps->size; 4. }
4-5按姓名来排序(题目要求使用直接插入排序来实现)
case 5: printf("按姓名来排序\n"); InsertSort(&ST);//直接插入排序函数接口调用 SeqListPrint(&ST);//排完序后打印顺序表,调用函数接口 printf("\n"); break;
函数接口:
void InsertSort(SeqList* ps) { for (int i = 0; i < ps->size - 1; i++) { int end = i; Student temp = ps->student[i + 1]; while (end >= 0) { if ((strcmp(ps->student[end].name,temp.name))>0)//字符数组比较大小使用strcmp函数 { ps->student[end + 1] = ps->student[end]; end--; } else { break; } } ps->student[end + 1] = temp; } }
4-6按学号来排序(题目要求使用快速排序来实现)
case 6: printf("按学号来排序\n"); QuickSort(&ST, 0, ST.size - 1);//快排函数接口调用 SeqListPrint(&ST);//顺序表打印函数接口调用 printf("\n"); break;