前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【顺序表&学生信息管理系统】学完顺序表就可以上高速写学生信息管理系统

【顺序表&学生信息管理系统】学完顺序表就可以上高速写学生信息管理系统

作者头像
MicroFrank
发布2023-01-16 11:43:39
4980
发布2023-01-16 11:43:39
举报
文章被收录于专栏:同步文章1234

相信数据结构的结课作业都有这种学生信息,图书管理系统,所以提前看一看还是很有必要的.(包含每一步代码和总源码)

(如果有需要可以参考我这篇博客:顺序表详解

https://blog.csdn.net/qq_64428099/article/details/124280862?spm=1001.2014.3001.5501

另外之前我也以为这个很难写,写完后的才知道这其实就是顺序表和排序的结合实现,只是额外增加了一点人机交互的一些输入输出而已,其实它很简单就可以实现.(耗时一下午左右就可完成)

 0.首先我们需要定义顺序表

代码语言:javascript
复制
typedef struct Student
{
	char id[18];
	char name[18];
	int grade;
}Student;//学生结构体类型重命名

typedef struct SeqList
{
	Student* student;//动态数组,方便后续扩容
	int size;
	int capacity;
}SeqList;//顺序表结构体类型重命名

你可以看成是顺序表这个盒子里面装着学生这个盒子的嵌套,盒子里面装着数组长度,学号之类的信息 

1.我们再在主函数里定义一个顺序表结构体变量,并调用初始化顺序表初始化接口 函数

代码语言:javascript
复制
    SeqList ST;
	SeqListInit(&ST);//调用顺序表初始化接口函数
代码语言:javascript
复制
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.为了更好的实现人机交互,这里我们用到打印菜单来方便用户选择 

代码语言:javascript
复制
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.主函数内的主要轮廓(有了轮廓之后就可以一步步实现这个代码,不要着急

代码语言:javascript
复制
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退出程序代码

代码语言:javascript
复制
		case 0:
			printf("退出程序\n");
			printf("\n");
			break;

4-1录入学生信息代码 

代码语言:javascript
复制
		//主函数代码:
          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;

 尾插建立顺序表的接口函数(和顺序表那里讲的一模一样)

代码语言:javascript
复制
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打印学生信息代码

代码语言:javascript
复制
		case 2:
			printf("打印学生信息\n");
			SeqListPrint(&ST);//调用打印函数接口
			printf("\n");
			break;

对应函数接口:

代码语言:javascript
复制
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指定位置插入学生信息代码:(题目要求使用指定的任意位置插入)

代码语言:javascript
复制
		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;

函数接口:

代码语言:javascript
复制
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统计学生个数

代码语言:javascript
复制
	case 4:
			printf("统计学生个数\n");
			int sz = SeqListSize(&ST);//调用函数接口并返回值用sz接收
			printf("当前统计表中学生的个数为:%d\n", sz);
			printf("\n");
			break;

函数接口:

代码语言:javascript
复制
int SeqListSize(SeqList* ps)
{
	return ps->size;
}

4-5按姓名来排序(题目要求使用直接插入排序来实现)

代码语言:javascript
复制
		case 5:
			printf("按姓名来排序\n");
			InsertSort(&ST);//直接插入排序函数接口调用
			SeqListPrint(&ST);//排完序后打印顺序表,调用函数接口
			printf("\n");
			break;

函数接口:

代码语言:javascript
复制
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按学号来排序(题目要求使用快速排序来实现)

代码语言:javascript
复制
		case 6:
			printf("按学号来排序\n");
			QuickSort(&ST, 0, ST.size - 1);//快排函数接口调用
			SeqListPrint(&ST);//顺序表打印函数接口调用
			printf("\n");
			break;

函数接口之快排:

(字符串相关函数可以参考我这篇博客)

字符串函数及其模拟实现

https://blog.csdn.net/qq_64428099/article/details/124113190?spm=1001.2014.3001.5501

代码语言:javascript
复制
void QuickSort(SeqList* ps,int left,int right)
{
	if (left > right) return;
	int begin = left, end = right;
	int keyi = left;
	while (left < right)
	{
		while (left < right && (strcmp(ps->student[right].id,ps->student[keyi].id)>= 0))
		{
			right--;
		}
		while (left < right && (strcmp(ps->student[left].id, ps->student[keyi].id)<= 0))
		{
			left++;
		}
		Swap(&ps->student[left], &ps->student[right]);
	}
	int meeti = left;
	
	Swap(&ps->student[meeti], &ps->student[keyi]);
	QuickSort(ps, begin, meeti - 1);
	QuickSort(ps, meeti + 1, end);

}

 函数调用之交换:

代码语言:javascript
复制
void Swap(Student* a, Student* b)//这个类型开始写的时候有点难受就是
{
	Student temp = *a;
	*a = *b;
	*b = temp;
}

4-7按学号查找学生信息(题目要求使用使用二分查找,二分查找前提是有序,因此我们要先进行排序)

代码语言:javascript
复制
		case 7:
			printf("查找学生信息\n");
			QuickSort(&ST, 0, ST.size - 1);//复用上个给学号排序的快排函数接口进行排序
			char findId[18]={0};
			printf("请输入你要查找的学生的学号:>");
			scanf("%s", findId);
			int ret=SeqListBinarySearch(&ST,findId);//调用二分查找函数接口
			if (ret == -1)
			{
				printf("统计表中不存在学号为%s的学生\n", findId);
			}
			else
			{
				printf("找到了!该学号为:%s的同学的姓名:%s\t成绩:%d\n", findId,ST.student[ret].name, ST.student[ret].grade);
			}
			printf("\n");
			break;

函数接口:

代码语言:javascript
复制
int SeqListBinarySearch(SeqList* ps, char* findId)
{
	int left = 0, right = ps->size - 1;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (strcmp(ps->student[mid].id, findId) == 0)
		{
			return mid;
			break;
		}
		else if (strcmp(ps->student[mid].id, findId) > 0)
		{
			right = mid - 1;
		}
		else
		{
			left = mid + 1;
		}
	}
	return -1;
}

4-8指定位置删除学生信息

代码语言:javascript
复制
	case 8:
			printf("删除学生信息\n");
			int locate = 0;
			printf("请输入你要删除的学生位置(目前可删除位置必须小于等于%d):>",ST.size);
			scanf("%d", &locate);
			SeqListDelete(&ST, locate-1);//删除元素函数接口
			printf("删除成功\n");
			printf("\n");
			break;

函数接口:

代码语言:javascript
复制
void SeqListDelete(SeqList* ps, int locate)
{
	int begin = locate+1;
	while (begin <= ps->size-1)//前移从前面那端开始移动
	{
		ps->student[begin-1] = ps->student[begin];
		begin++;
	}
	ps->size--;//勿漏
}

4.顺序表的销毁:题目虽然没有要求,但是这个必须加上!老师和我们说过动态内存开辟的空间要手动释放,毕竟谁开辟谁释放嘛,否则会损害公司的服务器!!!

函数接口:

代码语言:javascript
复制
void SeqListDestory(SeqList* ps)
{
	free(ps->student);
	ps->student = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

5.打印结果

 6.源码分享共有两个文件(test,c文件和seqlist.c文件)

test.c文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include"seqlist.h"
int main()
{

	SeqList ST;
	SeqListInit(&ST);
	int input = 0;
	//打印列表并且做出选择
	meau();
	do
	{
		printf("请输入你的选择:>");
		scanf("%d", &input);

		//根据菜单选择执行相应操作
		switch (input)
		{
		case 0:
			printf("退出程序\n");
			printf("\n");
			break;

		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;

		case 2:
			printf("打印学生信息\n");
			SeqListPrint(&ST);
			printf("\n");
			break;

		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;

		case 4:
			printf("统计学生个数\n");
			int sz = SeqListSize(&ST);
			printf("当前统计表中学生的个数为:%d\n", sz);
			printf("\n");
			break;

		case 5:
			printf("按姓名来排序\n");
			InsertSort(&ST);
			SeqListPrint(&ST);
			printf("\n");
			break;

		case 6:
			printf("按学号来排序\n");
			QuickSort(&ST, 0, ST.size - 1);
			SeqListPrint(&ST);
			printf("\n");
			break;

		case 7:
			printf("查找学生信息\n");
			QuickSort(&ST, 0, ST.size - 1);
			char findId[18]={0};
			printf("请输入你要查找的学生的学号:>");
			scanf("%s", findId);
			int ret=SeqListBinarySearch(&ST,findId);
			if (ret == -1)
			{
				printf("统计表中不存在学号为%s的学生\n", findId);
			}
			else
			{
				printf("找到了!该学号为:%s的同学的姓名:%s\t成绩:%d\n", findId,ST.student[ret].name, ST.student[ret].grade);
			}
			printf("\n");
			break;

		case 8:
			printf("删除学生信息\n");
			int locate = 0;
			printf("请输入你要删除的学生位置(目前可删除位置必须小于等于%d):>",ST.size);
			scanf("%d", &locate);
			SeqListDelete(&ST, locate-1);
			printf("删除成功\n");
			printf("\n");
			break;
		default:
			printf("输入有误,请重新输入\n");
			printf("\n");
			break;
		}

	} while (input);
	SeqListDestory(&ST);

}

seqlist,h文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1

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

typedef struct Student
{
	char id[18];
	char name[18];
	int grade;
}Student;

typedef struct SeqList
{
	Student* student;
	int size;
	int capacity;
}SeqList;

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");

}

void SeqListInit(SeqList* ps)
{
	ps->student = (Student*)malloc(sizeof(Student)*4);
	if (ps->student == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 4;
}

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++;
}

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);
	}
}

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++;
}

int SeqListSize(SeqList* ps)
{
	return ps->size;
}

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)
			{
				ps->student[end + 1] = ps->student[end];
				end--;
			}
			else
			{
				break;
			}
		}
		ps->student[end + 1] = temp;
	}
}

void Swap(Student* a, Student* b)
{
	Student temp = *a;
	*a = *b;
	*b = temp;
}

void QuickSort(SeqList* ps,int left,int right)
{
	if (left > right) return;
	int begin = left, end = right;
	int keyi = left;
	while (left < right)
	{
		while (left < right && (strcmp(ps->student[right].id,ps->student[keyi].id)>= 0))
		{
			right--;
		}
		while (left < right && (strcmp(ps->student[left].id, ps->student[keyi].id)<= 0))
		{
			left++;
		}
		Swap(&ps->student[left], &ps->student[right]);
	}
	int meeti = left;
	
	Swap(&ps->student[meeti], &ps->student[keyi]);
	QuickSort(ps, begin, meeti - 1);
	QuickSort(ps, meeti + 1, end);

}

int SeqListBinarySearch(SeqList* ps, char* findId)
{
	int left = 0, right = ps->size - 1;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (strcmp(ps->student[mid].id, findId) == 0)
		{
			return mid;
			break;
		}
		else if (strcmp(ps->student[mid].id, findId) > 0)
		{
			right = mid - 1;
		}
		else
		{
			left = mid + 1;
		}
	}
	return -1;
}

void SeqListDelete(SeqList* ps, int locate)
{
	int begin = locate+1;
	while (begin <= ps->size-1)
	{
		ps->student[begin-1] = ps->student[begin];
		begin++;
	}
	ps->size--;
}

void SeqListDestory(SeqList* ps)
{
	free(ps->student);
	ps->student = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云小微
腾讯云小微,是一套腾讯云的智能服务系统,也是一个智能服务开放平台,接入小微的硬件可以快速具备听觉和视觉感知能力,帮助智能硬件厂商实现语音人机互动和音视频服务能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档