给定学生成绩登记表如表9.1所示。
学号(num) |
姓名(name) |
成绩(grade) |
02 |
Lin |
92 |
03 |
Zhang |
87 |
04 |
Zhao |
72 |
05 |
Ma |
91 |
09 |
Zhen |
85 |
11 |
Wang |
100 |
12 |
Li |
86 |
13 |
Xu |
83 |
16 |
Mao |
78 |
17 |
Hao |
95 |
20 |
Lu |
82 |
21 |
Song |
76 |
22 |
Wu |
88 |
将表9.1划分成三个子表,其中子表1登记的是成绩在90~100之间的学生情况,子表2登记的是成绩在80~89之间的学生情况,子表3登记的是70~79之间的学生情况。
具体要求如下:
(1)用结构体数组存放表9.1中的学生成绩情况。其结构体类型为
struct student
{int num;
char name[10];
int grade:
}
(2)划分成的三个子表均采用链表结构,链表中各结点的数据域存放学生成绩情况在原表中的存储地址,而不是直接存放学生成绩情况。结点的结构为
struct node
{struct student *data;
struct node *next;
}
(3)要求最后输出原学生成绩情况表以及划分成的三个子表。输出格式如表9.1所示(但不要表中的框线)。
方法说明:
划分的方法如下:
扫描表9.1中各学生的成绩grade,计算
K=10-int(grade/10)
其中int()表示取整。根据k值将该学生情况归并到相应的子表中:
若k=0或1,则归并到子表1中;
若k=2,则归并到子表2中;
若k=3,则归并到子表3中。
在需要将学生情况加入到子表时,首先动态分配一个结点(struct node类型),将该学生情况在原表中的存储地址存入结点的数据域中,然后将该结点链接到相应链表的头部。
为了动态分配一个结点p,可以用如下语句:
p=(struet node*)malloc(sizeof(struct node));
其中p为结构体类型struct node的指针。
而为了使用函数malloc(),要求包含头文件”stdlib.h”。
#include<stdlib.h>
#include<conio.h>
#define N 13
typedef struct student
{
int num;
char name[10];
int grade;
}Stu;
Stu stu[N]={{2,"Lin",92},{3,"Zhang",87},{4,"Zhao",72},{5,"Ma",91},{9,"Zhen",85},{11,"Wang",100},{12,"Li",86},{13,"Xu",83},{16,"Mao",78},{17,"Hao",95},{20,"Lu",82},{21,"Song",76},{22,"Wu",88}};
typedef struct node
{
struct student *data;
struct node *next;
}Node;
void show(Node *h)
{
Node *p;
p=h;
while(p->next!=NULL)
{
printf("%d\t%s\t%d\n",p->data->num,p->data->name,p->data->grade);
p=p->next;
}
}
Node *create(Node *h,Stu *p)
{
Node *s;
s=(Node *)malloc(sizeof(Node));
h=s;
s->data=p;
s->next=NULL;
return h;
}
void save(Node *h,Stu *p)
{
Node *s,*t;
s=(Node *)malloc(sizeof(Node));
t=h;
while(t->next!=NULL)t=t->next;
s->data=p;
s->next=NULL;
t->next=s;
}
void main()
{
int i,j,k,flag[4]={0};
Node *h[4]={NULL},*p;
for(i=0;i<N;i++)
for(j=1;j<4;j++)
{
k=10-int(stu[i].grade/10);
if(k==0) k++;
if(k==j)
if(flag[j]==0)
{
flag[j]=1;
h[j]=create(h[j],&stu[i]);
}
else save(h[j],&stu[i]);
}
for(i=1;i<4;i++)
{
printf("The NO.%d table:\n",i);
show(h[i]);
}
getch();
}