#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define COURSE_NUM 5 /* 最多的考试科目 */
struct student
{
int number; /* 每个学生的学号 */
char name[15]; /* 每个学生的姓名 */
int score[COURSE_NUM]; /* 每个学生M门功课的成绩 */
int sum; /* 每个学生的总成绩 */
float average; /* 每个学生的平均成绩 */
struct student *next;
};
typedef struct student STU;
char Menu(void);
int ascending(int a, int b);
int descending(int a, int b);
void IntSwap(int *pt1, int *pt2);
void CharSwap(char *pt1, char *pt2);
void FloatSwap(float *pt1, float *pt2);
void InputNodeData(STU *pNew, int m);
STU *AppendNode(STU *head, STU **pNew);
STU *DeleteNode(STU *head, int nodeNum);
STU *ModifyNode(STU *head, int nodeNum, const int m);
STU *SearchNode(STU *head, int nodeNum);
STU *AppendScore(STU *head, const int m);
void TotalScore(STU *head, const int m);
void PrintScore(STU *head, const int m);
STU *DeleteScore(STU *head, const int m);
void ModifyScore(STU *head, const int m);
void SortScore(STU *head, const int m, int (*compare)(int a, int b));
void SearchScore(STU *head, const int m);
void DeleteMemory(STU *head);
void main()
{
char ch;
int m;
STU *head = NULL;
printf("Input student number(m<10):");
scanf("%d", &m);
while (1)
{
ch = Menu(); /* 显示菜单,并读取用户输入 */
switch (ch)
{
case'1':head = AppendScore(head, m); /* 调用成绩输入模块 */
TotalScore(head, m);
break;
case'2':PrintScore(head, m); /* 调用成绩显示模块 */
break;
case'3':head = DeleteScore(head, m); /* 调用成绩删除模块 */
printf("\nAfter deleted\n");
PrintScore(head, m); /* 显示成绩删除结果 */
break;
case'4':ModifyScore(head, m); /* 调用成绩修改模块 */
TotalScore(head, m);
printf("\nAfter modified\n");
PrintScore(head, m); /* 显示成绩修改结果 */
break;
case'5':SearchScore(head, m); /* 调用按学号查找模块 */
break;
case'6':SortScore(head, m, descending); /* 调用成绩排序模块,按总分降序对成绩排序 */
printf("\nAfter sorted in descending order by sum\n");
PrintScore(head, m); /* 显示成绩排序结果 */
break;
case'7':SortScore(head, m, ascending); /* 调用成绩排序模块,按总分升序对成绩排序 */
printf("\nAfter sorted in ascending order by sum\n");
PrintScore(head, m); /* 显示成绩排序结果 */
break;
case'0':exit(0); /* 退出程序 */
DeleteMemory(head); /*释放所有已分配的内存*/
printf("End of program!");
break;
default:printf("Input error!");
break;
}
}
}
/* 函数功能: 显示菜单并获得用户键盘输入的选项
函数参数: 无
函数返回值:用户输入的选项
*/
char Menu(void)
{
char ch;
printf("\nManagement for Students' scores\n");
printf(" 1.Append record\n");
printf(" 2.List record\n");
printf(" 3.Delete record\n");
printf(" 4.Modify record\n");
printf(" 5.Search record\n");
printf(" 6.Sort Score in descending order by sum\n");
printf(" 7.Sort Score in ascending order by sum\n");
printf(" 0.Exit\n");
printf("Please Input your choice:");
scanf(" %c", &ch); /*在%c前面加一个空格,将存于缓冲区中的回车符读入*/
return ch;
}
/* 函数功能: 输入一个节点的节点数据
函数参数: 结构体指针变量pNew,表示链表新添加节点的指针
整型变量m,表示考试科目
返回参数: 无
*/
void InputNodeData(STU *pNew, int m)
{
int j;
printf("Input node data......");
printf("\nInput number:");
scanf("%d", &pNew->number);
printf("Input name:");
scanf("%s", pNew->name);
for (j=0; j<m; j++)
{
printf("Input score%d:", j+1);
scanf("%d", pNew->score+j);
}
}
/* 函数功能: 向链表中添加从键盘输入的学生学号、姓名和成绩等信息
函数参数: 结构体指针head,指向存储学生信息的结构体数组的首地址
整型变量m,表示考试科目
函数返回值:无
*/
STU *AppendScore(STU *head, const int m)
{
int i = 0;
char c;
STU *pNew;
do{
head = AppendNode(head, &pNew); /*向链表末尾添加一个节点*/
InputNodeData(pNew, m); /*向新添加的节点中输入节点数据*/
printf("Do you want to append a new node(Y/N)?");
scanf(" %c",&c); /*%c前面有一个空格*/
i++;
}while (c=='Y' || c=='y');
printf("%d new nodes have been apended!\n", i);
return head;
}
/* 函数功能: 删除一个指定学号的学生的记录
函数参数: 结构体指针head,指向存储学生信息的链表的首地址
整型变量m,表示考试科目
函数返回值:删除学生记录后的链表的头指针
*/
STU *DeleteScore(STU *head, const int m)
{
int i = 0, nodeNum;
char c;
do{
printf("Please Input the number you want to delete:");
scanf("%d", &nodeNum);
head = DeleteNode(head, nodeNum);/*删除学号为nodeNum的学生信息*/
PrintScore(head, m); /*显示当前链表中的各节点信息*/
printf("Do you want to delete a node(Y/N)?");
scanf(" %c",&c); /*%c前面有一个空格*/
i++;
}while (c=='Y' || c=='y');
printf("%d new nodes have been deleted!\n", i);
return head;
}
/* 函数功能: 修改一个指定学号的学生的记录
函数参数: 结构体指针head,指向存储学生信息的链表的首地址
整型变量m,表示考试科目
函数返回值:修改学生记录后的链表的头指针
*/
void ModifyScore(STU *head, const int m)
{
int i = 0, nodeNum;
char c;
do{
printf("Please Input the number you want to modify:");
scanf("%d", &nodeNum);
head = ModifyNode(head, nodeNum, m); /*修改学号为nodeNum的学生信息*/
printf("Do you want to modify a node(Y/N)?");
scanf(" %c",&c); /*%c前面有一个空格*/
i++;
}while (c=='Y' || c=='y');
printf("%d new nodes have been modified!\n", i);
}
/* 函数功能: 计算每个学生的m门功课的总成绩和平均成绩
函数参数: 结构体指针head,指向存储学生信息的链表的首地址
整型变量m,表示考试科目
函数返回值:无
*/
void TotalScore(STU *head, const int m)
{
STU *p = head;
int i;
while (p != NULL) /*若不是表尾,则循环*/
{
p->sum = 0;
for (i=0; i<m; i++)
{
p->sum += p->score[i];
}
p->average = (float)p->sum / m;
p = p->next; /*让p指向下一个节点*/
}
}
/* 函数功能: 用交换法按总成绩由高到低排序
函数参数: 结构体指针head,指向存储学生信息的链表的首地址
整型变量m,表示考试科目
函数返回值:无
*/
void SortScore(STU *head, const int m, int (*compare)(int a, int b))
{
STU *pt;
int flag = 0, i;
do{
flag = 0 ;
pt = head;
/*若后一个节点的总成绩比前一个节点的总成绩高,则交换两个节点中的数据
注意只交换节点数据,而节点顺序不变,即节点next指针内容不进行交换*/
while (pt->next != NULL)
{
if ((*compare)(pt->next->sum, pt->sum))
{
IntSwap(&pt->number, &pt->next->number);
CharSwap(pt->name, pt->next->name);
for (i=0; i<m; i++)
{
IntSwap(&pt->score[i], &pt->next->score[i]);
}
IntSwap(&pt->sum, &pt->next->sum);
FloatSwap(&pt->average, &pt->next->average);
flag = 1;
}
pt = pt->next;
}
}while(flag);
}
/*交换两个整型数*/
void IntSwap(int *pt1, int *pt2)
{
int temp;
temp = *pt1;
*pt1 = *pt2;
*pt2 = temp;
}
/*交换两个实型数*/
void FloatSwap(float *pt1, float *pt2)
{
float temp;
temp = *pt1;
*pt1 = *pt2;
*pt2 = temp;
}
/*交换两个字符串*/
void CharSwap(char *pt1, char *pt2)
{
char temp[15];
strcpy(temp, pt1);
strcpy(pt1, pt2);
strcpy(pt2, temp);
}
/*决定数据是否按升序排序,a<b为真,则按升序排序*/
int ascending(int a, int b)
{
return a < b;
}
/* 决定数据是否按降序排序,a>b为真,则按降序排序 */
int descending(int a, int b)
{
return a > b;
}
/* 函数功能: 按学号查找学生成绩
函数参数: 结构体指针head,指向存储学生信息的链表的首地址
整型变量m,表示考试科目
函数返回值:�