1. 线性表的链式存储结构
实验目的
掌握线性表的链式存储结构及基本操作,深入了解顺序表的基本特性。
问题描述
某项比赛中,评委们给某参赛者的评分信息存储在一个带头结点的单向链表中,编写程序:
(1)显示在评分中给出最高分和最低分的评委的有关信息(姓名、年龄、所给分数等)。
(2)在链表中删除一个最高分和一个最低分的结点。
(3)计算该参赛者去掉一个最高分和一个最低分后的平均成绩。
实验要求
(1)建立一个评委打分的单向链表。
(2)显示删除相关结点后的链表信息。
(3)显示要求的结果。
请认真阅读以上实验的问题描述,按照实验要求认真独立完成实验。如果在实验过程中遇到困难,你可以通过以下辅助方式,顺利完成本实验。
如果对于本实验无从下手,你可以通过查看“设计思路”,帮助你开拓思维。设计思路
(1)评委信息结点用结构变量存储,包含三个成员项,即姓名、年龄、评分。结构类型定义如下:
//定义评委信息
struct pw
{
char name[8]; //姓名
short age; //年龄
国开答案请进:opzy.net或请联系微信:1095258436
float score; //评分
};
(2)用头插法或尾插法建立带头结点的单链表,本实验采用尾插法。
(3)遍历链表并逐次比较求最高分和最低分。
(4)在链表中物理删除,即实际删除最高分和最低分结点;也可以进行逻辑删除,即在被删结点的数据域设置一个删除标记,本实验采用物理删除的方法。
(5)遍历链表,累加求和,计算总分及平均分,并输出相关信息。
如果对于自己编写好的程序不知道是否正确,你可以查看“实验程序”进行核查。
如果对于自己编写的程序不知道是否正确,你可以通过查看“实验设计”进行核查。实验设计
程序代码如下:
//实验1.1 线性表的链接存储结构
#include
#include
#include
#define PWRS 5 //定义评委人数
//定义评委信息
struct pw
{
char name[8]; //姓名
short age; //年龄
float score; //评分
};
typedef struct pw PW;
//定义链表结点
struct node
{
PW data;
struct node * next;
};
typedef struct node NODE;
NODE *create(int n); //建立单链表
void input(NODE *s,int i); //输入第i个评委信息
void output(NODE *s); //输出评委信息
void traverse(NODE *head); //遍历链表
void calc(NODE *head); //计算及数据处理
void main()
{
NODE *head=NULL;
head=create(PWRS); //建立评委信息单链表
printf(“\n所有评委的评分信息如下:\n”);
traverse(head); //输出所有评委的评分信息
calc(head); //计算成绩
printf(“该参赛者去掉一个最高分和一个最低分后的有效评委的评分信息如下:\n”);
traverse(head); //输出有效评委的评分信息
}
//尾插法建立带头结点的单链表
NODE *create(int n)
{
NODE *head,*p,*q;
int i;
p=(NODE*)malloc(sizeof(NODE));
head=p; q=p; p->next=NULL;
for(i=1; i<=n; i++)
{
p=(NODE*)malloc(sizeof(NODE));
input(p,i);
p->next=NULL;
q->next=p;
q=p;
}
return (head);
}
//输入评委信息,包括姓名、年龄和评分
void input(NODE *s,int i)
{
printf(“请输入第 %d 个评委的姓名、年龄和评分:”,i);
scanf(“%s%d%f”,&s->data.name,&s->data.age,&s->data.score);
}
//输出评委信息
void output(NODE *s)
{
printf(“评委姓名:%6s 年龄:%d 评分:%6.2f\n”,s->data.name,s->data.age,s->data.score);
}
//遍历链表,输出所有评委的评分信息
void traverse(NODE *head)
{
NODE *p=head->next; //指向第一个结点
while(p!=NULL)
{
output(p);
p=p->next;
}
printf(“\n”);
}
//输出最高分及最低分评委信息,删除最高分及最低分结点并计算参赛者的最后平均分
void calc(NODE *head)
{
NODE *q,*p,*pmin,*pmax;
float sum=0; //总分
float ave=0; //平均分
//查找最高分和最低分并计算总分
p=head->next;
pmin=pmax=p;
while(p!=NULL)
{
sum+=p->data.score;
if(p->data.score>pmax->data.score) pmax=p; //pmax指向最高分结点
if(p->data.scoredata.score) pmin=p; //pmin指向最低分结点
p=p->next;
}
//输出最高分及最低分评委信息
printf(“给出最高分的评委姓名:%6s 年龄:%d 评分:%6.2f\n”,pmax->data.name,pmax->data.age,pmax->data.score);
printf(“给出最低分的评委姓名:%6s 年龄:%d 评分:%6.2f\n”,pmin->data.name,pmin->data.age,pmin->data.score);
printf(“\n”);
//去掉一个最高分和一个最低分,计算并输出参赛者的最后平均分
sum-=pmax->data.score;
sum-=pmin->data.score;
ave=sum/(PWRS-2);
printf(“该参赛者去掉一个最高分和一个最低分后的平均得分为:%6.2f\n”,ave);
printf(“\n”);
//在链表中删除最高分和最低分结点
for(q=head,p=head->next;p!=NULL;q=p,p=p->next)
{
if(p==pmin) { q->next=p->next; p=q; } //删除最低分结点
if(p==pmax) { q->next=p->next; p=q; } //删除最高分结点
}
}
如果已运行程序得出实验结果,你可以查看“测试结果”进行检测。测试结果
程序运行结果如下:
点击“实验小结”,看看通过本实验的学习,你有哪些收获。实验小结
(1)线性表采用链式存储(链表)时,用结构变量存储结点,动态生成结点,用指针链接结点,能有效利用存储空间,插入删除方便。
(2)链表不能随机访问,是顺序访问方式,可从某结点访问到其后继结点,通常对单链表的遍历即从表头结点顺序访问到表尾结点,任何在链表上做的查找运算都是在遍历的基础上进行的。
(3)单链表操作的关键步骤包括:
1)建立链表的头插法:指针变量 p 开辟单元,生成结点,指针变量 q 始终指向头结点;操作为:p->next=q->next; q->next=p;
2)建立链表的尾插法:指针变量 p 开辟单元,生成结点,指针变量 q 始终指向尾结点;操作为: q->next=p; q=p;
3)插入:p结点的后面插入新结点s;操作为:s->next=p->next; p->next=s;
4)删除:p,q 指向相邻结点,q结点是p结点的后继,删除q结点;操作为:p->next=q->next;
5)遍历:p指向后继结点;操作为:p=p->next;
2. 线性表的顺序存储结构
实验目的
掌握线性表的顺序存储结构及基本操作,深入了解顺序表的基本特性。
问题描述
用顺序表A记录学生的信息,编写程序:
(1)将A表分解成两个顺序表B和C,使C表中含原A表中性别为男性的学生,B表中含原表中性别为女性的学生,要求学生的次序与原A表中相同。
(2)分别求男生和女生的平均年龄。
实验要求
(1)建立学生信息的顺序表A。
(2)显示B表和C表中的相关信息。
(3)显示计算结果。
请认真阅读以上实验的问题描述,按照实验要求认真独立完成实验。如果在实验过程中遇到困难,你可以通过以下辅助方式,顺利完成本实验。
如果对于本实验无从下手,你可以通过查看“设计思路”,帮助你开拓思维。设计思路
(1)用结构数组存放学生的信息表,其中每个数组元素(结构变量)存放一个学生的相关信息,包含三个成员项,即姓名、性别、年龄。结构类型定义如下:
//定义学生信息
struct student
{
char name[8]; //姓名
short sex; //性别,1表示男,0表示女
short age; //年龄
};
(2)共设三个结构数组,一个用于存放所有学生信息,该顺序表需创建,另外两个用于存放结果,即分别存放女生信息和男生信息。表长存储在数组下标为0的单元中。
(3)通过扫描数组查询到性别信息,采用在顺序表的表尾插入数据的方法,将结果信息分别存放到B表和C表中。
(4)分别求B表和C表中学生的平均年龄。
如果对于自己编写的程序不知道是否正确,你可以通过查看“实验设计”进行核查。实验设计
程序代码如下:
//实验1.2 线性表的顺序存储结构
#include
define MAX 100 //定义数组大小
//定义学生信息
struct student
{
char name[8]; //姓名
short sex; //性别,1表示男,0表示女
short age; //年龄
};
typedef struct student List;
void create(List *a); //建立顺序表
void traverse(List *a); //输出学生信息
double average(List *a); //计算平均年龄
void split(List *a,List *b,List *c); //分解顺序表
void main()
{
List a[MAX],b[MAX],c[MAX]; //定义三个学生信息表
create(a);
printf(“A表所有学生信息如下:\n”);
traverse(a);
split(a,b,c); //将A表分解为B表和C表
printf(“B表女生信息如下:\n”);
traverse(b);
printf(“C表男生信息如下:\n”);
traverse(c);
printf(“女生平均年龄:%5.0lf\n”,average(b));
printf(“男生平均年龄:%5.0lf\n”,average(c));
}
//建立n个学生的顺序表
void create(List *a)
{
int n; //实际人数
printf(“请输入学生人数:”);
scanf(“%d”,&n);
a[0].age=n; //设置表长
for(int i=1; i<=n; i++)
{
printf(“请输入第 %d 个学生信息(姓名、性别(1表示男,0表示女)、年龄):”,i);
scanf(“%s%d%d”,a[i].name,&a[i].sex,&a[i].age);
}
printf(“\n”);
}
//输出学生信息
void traverse(List *a)
{
for(int i=1; i<=a[0].age; i++)
printf(“姓名:%6s 性别:%s 年龄:%d\n”,a[i].name,(a[i].sex==0?”女”:”男”),a[i].age);
printf(“\n”);
}
//计算平均年龄
double average(List *a),/
{
int sum=0;
for(int i=1; i<=a[0].age; i++)
sum+=a[i].age;
return double(sum)/a[0].age;
}
//将a表分解成两个顺序表b和c,b表含性别为女的学生,c表含性别为男的学生
void split(List *a,List *b,List *c)
{
b[0].age=c[0].age=0; //清空表
for(int i=1; i<=a[0].age; i++)
{
if(a[i].sex==0)
{
b[0].age++;
b[b[0].age]=a[i];
}
else{
c[0].age++;
c[c[0].age]=a[i];
}
}
}
如果已运行程序得出实验结果,你可以查看“测试结果”进行检测。测试结果
程序运行结果如下:
点击“实验小结”,看看通过本实验的学习,你有哪些收获。实验小结
(1)线性表采用顺序存储(顺序表)时,利用数组存放表中数据,存储简单直观,并能根据数组下标随机访问表中任意一个元素。
(2)顺序表不适宜在表中做插入或删除操作,会产生大量数据移动,效率低,但在表尾插入元素或删除表尾元素则不需要移动数据,速度快。
(3)线性表的长度是可变的,顺序表中插入操作时表长加1,删除操作时表长减1。
完成这个实验的成绩占形成性考核成绩的20%,你可以在这里提交。