您的位置:首页 > 理论基础 > 数据结构算法

数据结构实验 第一单元 学生成绩管理系统(链表版)

2015-11-29 23:11 465 查看
#define _TABLE_STU_PRINT_LEVEL_LINE printf("**************************************************\n");
#define _TABLE_STU_PRINT_COL_TITLE printf("学号      姓名     数学   语文   英语   化学    物理  \n");
#define _TABLE_STU_PRINT_LINE printf("%-10s%-9s%-7.1f%-7.1f%-7.1f%-7.1f%-6.1f\n",stu->num,stu->name,stu->math,stu->cn,stu->eng,stu->che,stu->phy);

typedef struct
{
char num[11];
char name[11];
float math;
float cn;
float eng;
float che;
float phy;
}Student;

typedef struct stuNode
{
Student data;
struct stuNode *next;
}StuLinkedList;

//置空表
void InitStuList(StuLinkedList *L)
{
L->next = NULL;
}
//获取表长
int GetStuListLength(StuLinkedList *L)
{
StuLinkedList *p;
int len = 0;
p = L->next;
while (p != NULL)
{
len++;
p = p->next;
}
return len;
}

//取结点,查找链表中的第pos个位置(从1开始计数)的元素。未找到返回NULL。
StuLinkedList* GetStuListElem(StuLinkedList *L, int pos)
{
//获取表长
int now = 0;
StuLinkedList *p = L->next;
//超出范围
if (pos > GetStuListLength(L) || pos<1)
return NULL;
//查找。。
while (p != NULL)
{
now++;
if (now == pos)
{
return p;
}
else
{
p = p->next;
}
}
return NULL;
}

//带头结点的单链表。查找指定学号的学生所在结点,未找到返回NULL
StuLinkedList* LocateStuListElemByNum(StuLinkedList* L, char num[])
{

StuLinkedList* p = L->next;
while (p != NULL)
{
if (strcmp(p->data.num, num) == 0)
{
return p;
}
else
{
p = p->next;
}
}
return NULL;

}

//获取学生所在的位置。从1开始计数。
int GetStuPosByNum(StuLinkedList* L,char num[])
{
StuLinkedList* p = L->next;
int pos = 0;
while (p != NULL)
{
pos++;
if (strcmp(p->data.num, num) == 0)
{
return pos;
}
else
{
p = p->next;
}
}
return -1;
}

//带头结点的单链表。插入元素。pos:插入位置。key插入值,成功返回1,插入失败返回0。
int InsertStuList(StuLinkedList *L, int pos, Student key)
{
StuLinkedList *p, *newNode;
int len = GetStuListLength(L);
//新建结点
newNode = new struct stuNode;
newNode->data = key;
newNode->next = NULL;
//检查插入范围
if (pos >= 1 && pos <= len + 1)
{
//插入到1~len之间
p = GetStuListElem(L, pos - 1);
if (p == NULL)
{
//必为空表中插入第一个元素
L->next = newNode;
return 1;
}
newNode->next = p->next;
p->next = newNode;
return 1;
}
else
{
return 0;
}
}

//带头结点的单链表。删除pos这个位置的元素,并且将这个元素的值保存在e中。删除成功返回1,失败返回0。
int DelStuListElem(StuLinkedList *L, int pos, Student *e)
{
StuLinkedList *p, *pre;
int len = GetStuListLength(L);
if (pos<1 || pos> len)
return 0;
//得到该位置的元素
p = GetStuListElem(L, pos);
if (p == NULL)
return 0;
//得到该位置的前一个元素
pre = GetStuListElem(L, pos - 1);
if (pre == NULL)
{
//说明pos是第一个位置
pre = L;
}
if (e != NULL)
*e = p->data;
pre->next = p->next;
return 1;
}

//带头结点的单链表。建立链表。尾插法。
StuLinkedList* CreateStuListR(Student stus[], int n)
{
StuLinkedList *L = new StuLinkedList, *p, *pre;
int i;
L->next = NULL;
pre = L;
for (i = 0; i<n; i++)
{
p = new struct stuNode;
p->data = stus[i];
p->next = NULL;
pre->next = p;
pre = p;
}
return L;
}

//带头结点的单链表。建立链表。头插法。
StuLinkedList* CreateStuList(Student stus[], int n)
{
StuLinkedList *L = new StuLinkedList, *p, *pre;
int i;
L->next = NULL;
pre = L;
for (i = 0; i<n; i++)
{
p = new struct stuNode;
p->data = stus[i];
p->next = L->next;
L->next = p;
}
return L;
}

//释放链表
void DeleteList(StuLinkedList* &L)
{
StuLinkedList *p = L->next, *del;

while (p != NULL)
{
//delete并不会改变p的值
//它只是将p指向的那块内存释放了
del = p;
p = p->next;
delete del;
}
delete L;
L = NULL;
}

//带头结点的单链表。按照结点顺序,以字符方式输出链表。
void PrintStuList(StuLinkedList *L)
{
StuLinkedList *p = L->next;
Student *stu;
putchar('\n');
_TABLE_STU_PRINT_LEVEL_LINE
_TABLE_STU_PRINT_COL_TITLE
while (p != NULL)
{
//将stu按照顺序型输出
stu = &(p->data);
_TABLE_STU_PRINT_LINE
p = p->next;
}
_TABLE_STU_PRINT_LEVEL_LINE
printf("\n");
}

void PrintSingleStu(Student stuObj)
{
Student *stu = &stuObj;
_TABLE_STU_PRINT_LEVEL_LINE
_TABLE_STU_PRINT_COL_TITLE
_TABLE_STU_PRINT_LINE
_TABLE_STU_PRINT_LEVEL_LINE
}

Student* ToArray(StuLinkedList* L, int *length)
{
int len = GetStuListLength(L), i = 0;
Student* dt = new Student[len];
StuLinkedList *p = L->next;
while (p != NULL)
{
dt[i++] = p->data;
p = p->next;
}
*length = len;
return dt;
}

//获取用户输入学生信息,封装成结构体
Student GetStuByInput()
{
Student stu;
printf("请输入学生学号:"); scanf("%s", stu.num);
printf("请输入学生姓名:"); scanf("%s", stu.name);
printf("请输入数学成绩:"); scanf("%f", &(stu.math));
printf("请输入语文成绩:"); scanf("%f", &(stu.cn));
printf("请输入英语成绩:"); scanf("%f", &(stu.eng));
printf("请输入化学成绩:"); scanf("%f", &(stu.che));
printf("请输入物理成绩:"); scanf("%f", &(stu.phy));
return stu;
}

//返回修改后的学生
Student GetModifiedStu(Student sourceStu)
{
char str[20];
double dInp;
Student stu;
stu = sourceStu;
PrintSingleStu(sourceStu);
printf("请填写一下修改项\n");
printf("修改学号,输入/不修改:"); scanf("%s", str);
if (!(str[0] == '/' && str[1]==0) )
{
strcpy(stu.num, str);
}
printf("修改姓名,输入/不修改:"); scanf("%s", str);
if (!(str[0] == '/' && str[1] == 0))
{
strcpy(stu.name, str);
}
printf("修改数学成绩,不修改输入-1:"); scanf("%lf", &dInp);
if (dInp >0)
{
stu.math = dInp;
}
printf("修改语文成绩,不修改输入-1:"); scanf("%lf", &dInp);
if (dInp > 0)
{
stu.cn = dInp;
}

printf("修改英语成绩,不修改输入-1:"); scanf("%lf", &dInp);
if (dInp > 0)
{
stu.eng = dInp;
}
printf("修改化学成绩,不修改输入-1:"); scanf("%lf", &dInp);
if (dInp >0)
{
stu.che = dInp;
}
printf("修改物理成绩,不修改输入-1:"); scanf("%lf", &dInp);
if (dInp>=0)
{
stu.phy = dInp;
}

return stu;
}

//成功返回1
int ModifyStuByNum(StuLinkedList *L,Student stu)
{
if (L == NULL)
return 0;
StuLinkedList *stuLink = LocateStuListElemByNum(L, stu.num);
if (stuLink != NULL)
{
stuLink->data = stu;
return 1;
}
else
{
return 0;
}
}

//成功返回1
int DelStuByNum(StuLinkedList *L,char num[])
{

if (L == NULL)
return 0;
int stuPos = GetStuPosByNum(L, num);
return DelStuListElem(L, stuPos, NULL);

}

//全局变量
StuLinkedList *global_List = CreateStuList(NULL, 0);

//返回0,表示退出系统;返回非0,则继续循环。
int Menu()
{
system("cls");
printf("                   欢迎使用学生成绩管理系统\n");
printf("          1.查看所有学生             2.添加学生信息\n");
printf("          3.修改学生信息             4.删除所有学生\n");
printf("          5.退出管理系统                         \n");
printf("          当前学生数量:%d \n", GetStuListLength(global_List));
printf("          请输入操作编号:");
int oprNum;
scanf("%d%*c", &oprNum);
//清除菜单选项,
system("cls");
switch (oprNum)
{
case 1:
PrintStuList(global_List);
system("pause");
return 1;
case 2:
{
Student stu = GetStuByInput();
int res = InsertStuList(global_List, 1+GetStuListLength(global_List), stu);
if (res)
{
printf("添加成功,按任意键返回到主菜单!\n");
}
else
{
printf("添加失败!!按任意键返回到主菜单!\n");
}
system("pause");
}
return 1;
case 3:
{
char num[20];
StuLinkedList *stuL;
Student stu;
int res;
//1. 显示学生列表
PrintStuList(global_List);
//2. 获取欲修改的学生的学号
printf("请输入要修改的学生的学号:");
gets(num);
stuL = LocateStuListElemByNum(global_List, num);
if (stuL == NULL)
{
printf("未找到该学生!按任意键返回到主菜单!\n");
system("pause");
return 1;
}
stu = stuL->data;
//3. 输入修改信息
stu = GetModifiedStu(stu);
//4. 执行修改命令
res = ModifyStuByNum(global_List,stu);
if (res == 1)
{
printf("修改成功,按任意键返回到主菜单!\n");
}
else
{
printf("修改失败!!按任意键返回到主菜单!\n");
}
system("pause");
return 1;
}
case 4:
{
//1. 获取欲删除的学生学号
char num[20];
Student stu;
int res;
//1.1 显示学生列表
PrintStuList(global_List);
//1.2 获取欲删除的学生的学号
printf("请输入要删除的学生的学号:");
gets(num);
res = DelStuByNum(global_List,num);
if (res)
{
printf("删除成功,按任意键返回到主菜单!\n");
}
else
{
printf("删除失败!!按任意键返回到主菜单!\n");
}
system("pause");
}
return 1;
case 5:
return 0;
break;
default:
printf("您输入的编号格式错误!请重新输入");
system("pause");
return 1;
}
}

void Welcome()
{

printf("                   欢迎使用学生成绩管理系统\n");
printf("                   作者:软件1402班 何健伟\n");
printf("                   学号:201416080228\n");
printf("                   日期:2015年11月27日\n");
system("pause");
}

void GoodBye()
{
printf("            .......谢谢您的使用!.......\n");
system("pause");
}
void TestStudentOpr()
{

Welcome();
while (Menu());
GoodBye();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: