某末流211大学计算机类专业。
大一上的C语言课,大一下暑假前的小学期做的实验。
之前对链表只是大致了解,打ACM也用的很少,经过这次实验,还是深入地了解了链表和文件输入输出的应用。
原理都不难,直接贴代码了,仔细看一看应该是可以看懂的,希望参考的同学还是自己动手画一画链表链接、删除等操作,真的是理解和掌握链表的捷径。
我们老师要求做成三个cpp文件,分别是主函数部分、自定义函数的声明和自定义函数,仔细看看不难看懂,合并到一个cpp里也不难,大家可以自行发挥。
第一部分:主函数
#include
#include
#include
#include
#define len sizeof(struct student)
#include"声明.cpp"
#include"自定义函数.cpp"
//主函数
int main()
{
char s[15];
struct student *head;
while(1)
{
printf("请输入功能编号完成相应功能\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");
printf("9.删除某个班级、某门课程的成绩小于某个分数的学生\n");
printf("10.按照姓名排序\n");
printf("11.保存当前信息\n");
printf("其他,推出系统\n");
int x,z;
char y[10];
struct student *h,*k;
scanf("%d",&x);
switch(x)
{
case(1):
h=input();
save(h);
break;
case(2):
printf("请输入要查找的文件名:\n");
getchar();
gets(s);
head=creatlist(s);
printf("\n");
printf("注册链表成功\n");
break;
case(3):
printf("请输入要删除的学生的学号:\n");
scanf("%s",y);
head=del(head,y);
break;
case(4):
printf("请按顺序输入要插入的信息,用空格隔开\n");
insert(head);
print(head);
break;
case(5):
printf("当前信息如下:\n");
print(head);
break;
case(6):
printf("总成绩最高的学生信息如下\n");
printf("\n学号\t姓名\t专业 \t\t班级 成绩0 成绩1 成绩2 \t\n");
outone(MAX(head));
break;
case(7):
printf("按学号查找请按0,按姓名查找请按1:\n");
scanf("%d",&z);
if(z==0)
{
head=numfind(head);
print(head);
}
if(z==1)
{
head=namefind(head);
print(head);
}
if(z!=0&&z!=1)
printf("请按要求输入!!!!!\n");
break;
case(8):
head=search_major_score(head);
print(head);
break;
case(9):
head=del_class_score(head);
print(head);
break;
case(10):
namesort(head);
print(head);
break;
case(11):
save(head);
break;
default:
break;
}
}
return 0;
}
第二部分:自定义函数声明
//定义结构体
struct student{
char num[10];//学号
char name[15];//姓名
char major[10];//专业computer,softwear,network
int classNo;//班级
int score[3];//3门课的成绩
int sum;//3门课的总成绩
struct student *next;//指针 88u
};
//定义全局变量
int n;int a;
//函数声明
struct student *input();
struct student *creatlist(char *filename);
void save(student *head);
void print(struct student*head);
struct student *del(struct student *head,char z[]);
struct student *insert(struct student*head);
void outone(struct student *temp);
struct student *MAX(struct student*head);
struct student *numfind(struct student *head);
struct student *namefind(struct student *head);
struct student *search_major_score(struct student *head);
struct student *del_class_score(struct student *head);
void namesort(struct student *head);
第三部分:自定义函数
//输入学生信息
struct student *input()
{
n=0;
printf("请输入学生人数\n");
scanf("%d",&a);
printf("请录入这%d名学生的信息:\n",a);
struct student *head;
struct student *p1,*p2;
head=(struct student*)malloc(len);
while(n<a)
{
p1=(struct student*)malloc(len);
scanf("%s%s%s%d%d%d%d",&p1->num,&p1->name,&p1->major,&p1->classNo,&p1->score[0],&p1->score[1],&p1->score[2]);
p1->sum=0;
p1->sum=p1->score[0]+p1->score[1]+p1->score[2];//计算分数之和
n++;
if(n==1)//特判第一波
head->next=p1;
else
p2->next=p1;
p2=p1;
}
p2->next=NULL;//注意最后附空值
return(head);
}
//从文件中读取学生信息,并建立链表
struct student *creatlist(char *filename)
{
student *s,*p,*head; //s为当前节点 ,head为头节点
FILE *fp;
if((fp=fopen(filename,"rb"))==NULL)
{
printf("Wrong.");
exit(0);
}
head=(student *)malloc(sizeof(student)); //开辟内存
s=(student *)malloc(sizeof(student)); //开辟内存
if((fread(s,sizeof(student),1,fp))==NULL)
{
printf("Wrong.");
exit(0);
}
head->next=s;
p=s;
while(s->next!=NULL)
{
s=(student *)malloc(sizeof(student));
fread(s,sizeof(student),1,fp);//读取数据
p->next=s;//赋值
p=s;
}
return head;
}
//保存数据文件
void save(student *head)
{
struct student *p;
p=head->next;//从第二个开始保存
FILE *fp;
char filename[15];
printf("请输入要建立的文件的名称:\n");
scanf("%s",&filename);
if((fp=fopen(filename,"wb"))==NULL)
{
printf("Wrong.");
exit(0);
}
while(p!=NULL)
{
if(fwrite(p,sizeof(student),1,fp)!=1)
{
printf("写入文件失败\n");
}
p=p->next;
}
printf("写入文件成功!\n");
fclose(fp);
}
//打印有头节点
void print(struct student*head)
{
struct student *p;
printf("\n学号\t姓名\t专业 \t\t班级 成绩0 成绩1 成绩2 \t");
p=head->next;//从第二个开始打印
while(p!=NULL)
{
printf("\n%s\t%-6s\t%-10s\t%d\t%d\t%d\t%d\t", p->num, p->name, p->major,p->classNo,p->score[0],p->score[1],p->score[2]);
p=p->next;//循环
}
printf("\n");
}
//按学号删除学生信息
struct student *del(struct student *head,char z[])
{
struct student *p,*q,*k;
q=head;
p=head->next;//q为前置节点,p为当前节点
int w=atoi(z),e=atoi(p->num);//字符转整形
if(head==NULL)
printf("Wrong.\n");
while(w!=e&&p->next!=NULL)//判断是否符合条件
{
q=q->next;
p=p->next;
e=atoi(p->num);
}
if(w==e)//停止原因1:符合条件
{
printf("被删除的学生的信息是:\n");
printf("\n学号\t姓名\t专业 \t\t班级 成绩0 成绩1 成绩2 \t\n");
outone(p);
printf("\n");
printf("确定要删除此人信息?输入'1'确认删除,输入'0'取消删除:\n");
int y;
scanf("%d",&y);
if(y==1)
{
q->next=p->next;//跳过该节点,链接下一节点
printf("删除成功!\n");
printf("新的学生信息如下:\n");
print(head);
}
if(y==0)
{
printf("取消删除成功!\n");
}
}
else//停止原因2:查无此人
{
printf("很抱歉,系统查无此人\n");
}
return(head);
}
//按学号插入学生信息
struct student *insert(struct student*head)
{
struct student *temp;
struct student *p;
temp=(student *)malloc(sizeof(student));
p=head;
printf("\n学号\t姓名\t专业 \t\t班级 成绩0 成绩1 成绩2 \t\n");
scanf("%s%s%s%d%d%d%d",&temp->num,&temp->name,&temp->major,&temp->classNo,&temp->score[0],&temp->score[1],&temp->score[2]);
temp->sum=temp->score[0]+temp->score[1]+temp->score[2];//注意计算分数总和
while(p!=NULL)
{
int g=atoi(p->next->num);int b=atoi(temp->num);//字符转化整形
if(g>b)//判断:符合条件进行插入
{
temp->next=p->next;
p->next=temp;
break;
}
else//不符合条件后移一位
{
p=p->next;
g=atoi(p->next->num);
if(p->next==NULL)//特判,否则出错
{
p->next=temp;
temp->next=NULL;
break;
}
}
}
return(head);
}
//输出一个节点信息
void outone(struct student *temp)
{
printf("%s\t%-6s\t%-10s\t%d\t%d\t%d\t%d\t\n", temp->num, temp->name, temp->major,temp->classNo,temp->score[0],temp->score[1],temp->score[2]);
}
//寻找成绩最高的学生
struct student *MAX(struct student*head)
{
struct student *p,*maxn;
p=head;
int big=p->sum;//big记录当前最大值
maxn=p;
while(p!=NULL&&p->next!=NULL)//遍历一遍,找到分数最大节点
{
p=p->next;
if(p->sum>=big)//与big值比较
{
big=p->sum;
maxn=p;
}
}
return(maxn);
}
//寻找指定学号的学生并修改该学生信息
struct student *numfind(struct student *head)
{
int flag=0;
char x[15];
printf("请输入学号:\n");
scanf("%s",x);
struct student *p;
p=head;
while(p!=NULL)
{
if(strcmp(p->num,x)==0)//字符串比较函数判断学号是否相同
{
printf("请按以下顺序修改该学生信息");
printf("\n学号\t姓名\t专业 \t\t班级 成绩0 成绩1 成绩2 \t\n");
scanf("%s%s%s%d%d%d%d",&p->num,p->name,p->major,&p->classNo,&p->score[0],&p->score[1],&p->score[2]);//重新修改
flag++;
break;
}
p=p->next;
}
if(flag!=0)//flag特判
printf("修改成功!新信息如下:\n");
else
printf("抱歉,系统查无此人!\n");
return(head);
}
//寻找指定姓名的学生并修改学生信息
struct student *namefind(struct student *head)
{
int flag=0;
char x[15];
printf("请输入姓名:\n");
scanf("%s",x);
struct student *p;
p=head;
while(p!=NULL)
{
if(strcmp(p->name,x)==0)//字符串比较函数查姓名
{
printf("请按以下顺序修改该学生信息");
printf("\n学号\t姓名\t专业 \t\t班级 成绩0 成绩1 成绩2 \t\n");
scanf("%s%s%s%d%d%d%d",&p->num,p->name,p->major,&p->classNo,&p->score[0],&p->score[1],&p->score[2]);//重新修改
flag++;
break;
}
p=p->next;
}
if(flag!=0)//flag特判
printf("修改成功!新信息如下:\n");
else
printf("抱歉,系统查无此人!\n");
return(head);
}
//查找某个专业、某门课程的成绩小于某个分数的学生
struct student *search_major_score(struct student *head)
{
struct student *p,*q,*xin,stu1;
q=(student *)malloc(sizeof(student));//新开辟内存,建立新链表
xin=q;
p=head;
char a[15];
int x,i;
printf("请输入专业:");
scanf("%s",a);
printf("请输入课程编号(0-2):");
scanf("%d",&i);
printf("请输入分数:");
scanf("%d",&x);
while(p!=NULL)
{
if(strcmp(p->major,a)==0)
{
if(p->score[i]<x)
{
q->next=(student *)malloc(sizeof(student)); //开辟内存,新存数据
q=q->next; //注意建立带头节点的链表
strcpy(q->num,p->num);strcpy(q->major,p->major);strcpy(q->name,p->name);
q->score[0]=p->score[0];q->score[1]=p->score[1];
q->score[2]=p->score[2];q->sum=p->sum;q->classNo=p->classNo;
}
}
p=p->next;
}
q->next=NULL;//注意最后附空值
return(xin);
}
//删除某个班级、某门课程的成绩小于某个分数的学生
struct student *del_class_score(struct student *head)
{
struct student *p,*q;
q=head;
p=head->next;
int a,i,x;
printf("请输入班级:");
scanf("%d",&a);
printf("请输入课程编号(0-2):");
scanf("%d",&i);
printf("请输入分数:");
scanf("%d",&x);
while(p!=NULL)
{
if(p->classNo==a&&p->score[i]<x)
{
q->next=p->next;//符合条件,跳过该节点进行删除
p=q->next;//注意不要忘记p要重新换位置
}
else//不符合条件,pq一起后移一位
{
p=p->next;
q=q->next;
}
}
q=NULL;//最后附空值
return(head);
}
//按照姓名排序
void namesort(struct student *head)
{
struct student *front,*min,*rear,*p,*count;
int j=0;
count=head;
while(count!=NULL)
{
j++;//计数器记录共有多少学生的信息
count=count->next;
}
min=head->next;
p=head->next;
rear=head;//rear为前置节点
for(int i=0;i<j-1;i++)//第一次循环,找最值
{
while(p)//第二次循环进行比较
{
if(!p->next)//特判,否则会出错
{
p=p->next;
continue;
}
if(strcmp(p->next->name,min->name)<0)//字符串比较函数
{
min=p->next;//移动变换
front=p;
}
p=p->next;//下一个节点
}
if(min==rear->next)//如果循环一圈,没有找到新的最大值
{
rear=min;
min=min->next;
p=min;
}
else//循环一圈,有新的最大值
{
front->next=min->next;
min->next=rear->next;
rear->next=min;
rear=min;
min=min->next;
p=min;
front=p;
}
}
}