当前位置:首页 >> 数学 >>

实验七 结构体与链表


实验七结构体与链表
一、目的和要求
1. 掌握结构体类型、结构体变量的基本概念; 2. 掌握结构体指针、结构体数组的应用; 3. 掌握链表的基本概念; 4. 掌握链表的基本操作与应用,包括建立链表、遍历链表、插入结点、删除结点、 查找结点等。

二、实验设备及分组
1. Windows XP 操作系统; 2. Visual C++6.0 语言环境; 3. 每人一台 PC 机。

三、内容和步骤
(一)验证实验程序
1.用三种方式定义职工、学生、日期等结构体变量。 解: # include <iostream.h> # include <string.h> struct employee //定义职工结构体数据类型 { int no ; //职工编号 char name[8]; //职工姓名 char addr[40]; //家庭地址 }; struct student //定义学生结构体数据类型 { int no; //学号 float eng,phy,math,ave; //英语、数学、物理成绩、平均成绩 } stu1,stu2; //定义结构体同时定义结构体变量 stu1、stu2 void main () { employee emp1,emp2; //定义 employ 类型的结构体变量 emp1、emp2。 struct { intyear,month,day; } date1,date2; //直接定义日期结构体类型变量。 emp1.no=100; //赋职工号 strcpy ( emp1.name, "zhangsa"); //赋职工姓名 strcpy( emp1.addr, "Nanging"); //赋家庭地址 emp2=emp1; //将职工 emp1 的信息赋给 emp2 cout<<"no="<< emp2.no<<'\t' //输出职工信息 <<"name="<< emp2.name<<'\t' << "addr="<< emp2.addr<<endl; stu1.no=101; //输入学号与成绩 stu1.eng=90; //输入成绩

stu1.phy=95; stu1.math=100; cout<<"eng="<<stu1.eng<<'\t' //输出学生成绩 <<"phy="<<stu1.phy<<'\t' <<"math="<<stu1.math<<endl; date1.year=1999; //输入入学日期 date1.month=09; date1.day=01; cout<<"year="<<date1.year<<'\t' //输出入学日期 <<"month="<<date1.month<<'\t' <<"day="<<date1.day<<endl; } 2.编写程序完成一名职工的姓名、出生年月、奖惩、基本工资的初始化。从键盘输入 奖金金额,输出对应职工的姓名、工龄、奖惩、领取金额等信息。 分析:姓名、出生年月、奖惩、基本工资为不同的数据类型,组成一个有机整体,可以 用结构体进行处理,其中出生年月也用结构体来定义。 解: 一个完整的参考程序如下: #include<iostream.h> struct Date { int year; int month; }; //A struct Person { char name[20]; Date birth; char award[20]; float money; float salary; }p={"南苯",{1966,10},"五一劳动奖章",896,0}; void main() { floatnum; cout<<p.name<<","<<p.award; cout<<",基本工资:"<<p.money<<endl<<"请输入奖金金额:"; cin>>num; p.salary= p. money+num; cout<< p.name <<",年龄"<<2003- p. birth.year; cout<<",应领"<<p.salary<<"元"<<endl; } 思考: ? 删去 A 行的“;”号,运行程序,观察结果,分析原因; ? 修改程序,将结构体变量的定义放在 main()函数内,再运行程序,观察结果,分 析原因;

? 修改程序,将结构体类型定义保存为头文件 Person.h,采用#include 命令实现本程 序的功能。 ? 修改程序输出三名职工的姓名、工龄、奖惩、领取金额等信息。 3.设链表结点数据结构为: struct node { char name[8]; int score; node *next; }; 编写程序,实现下列链表的基本操作。 (1)建立无序链表。 (2)输出链表上各结点数据。 (3)删除整个链表 (4)删除链表中某个结点数据。 (5)将结点插入到链表指定位置。 (6)建立有序链表 解: 建立链表: node * Create(void ) { int score; //定义输入学生成绩的临时变量 score node *head,*pn,*pt; //定义链表头指针、新结点指针、尾指针 head、pn、pt。 head=0; //链表头指针赋 0,表示链表为空。 cout<<"产生链表,请输入学生成绩与姓名,以-1 为结束:"<<endl; cin>>score; //输入学生成绩 while (score!= -1) //成绩为-1 时结束输入 { pn= new node; //动态分配新结点内存空间,并将结点地址赋给 pn。 pn->score=score; //将学生成绩输入新结点 cin>>pn->name ; //学生姓名输入新结点 if (head==0) //若链表为空 { head=pn; //则将新结点地址由 pn 赋给头指针 head 与尾指针 pt pt=pn; //使新结点加入到链首 } else //否则链表非空 { pt->next=pn; //将新结点地址由 pn 赋给链尾的 next 指针与尾指针 pt pt=pn; //使新结点加入到链尾 } cin>>score; //输入学生成绩 } pt->next=0; //链尾指针变量赋 0 return (head); //返回链表的头指针 } 输出链表: void Print(const node *head) { const node *p; p=head; cout<<”输出链表中各结点值:”<<endl;

while (p!=0 ) { cout<<p->name<<’\t’<<p->score<<endl; p=p->next; } } 删除链表: voidDelchain(node * head) { node * p; p=head; //链表头指针赋给 p while (head) //当链表非空时删除结点 { head=p->next; //将链表下一个结点指针赋给 head delete p; //删除链表第一个结点 p=head; //再将头指针赋给 p } } 删除链表上指定值的结点: node * Delete( node *head, char name[]) { node *pc,*pa,*headtemp; headtemp=pc=pa=head; if (head==NULL) //链表为空的情况 { cout<< "链表为空,无结点可删!\t"; return NULL; } if (strcmp(pc->name,name)==0) // 第一个结点为要删除结点的情况 { head=pc->next; //将第二个结点的地址赋给 head, //使首结点从链表中分离出来 delete pc; //删除首结点 cout<<"删除了一个结点!\n"; } else //第一个结点不是要删除的结点 { while (strcmp(pc->name,name)) //查找要删除的结点 { pa=pc; //当前结点地址由 pc 赋给 pa pc=pc->next; //pc 指向下一个结点 } if (pc==NULL) //若 pc 为空表示链表中无要删除的结点 cout<< "链表中没有要删除的结点!\n"; else { pa->next=pc->next; //将下结点地址赋给上结点, //使删除结点从链表分离出来 delete pc; //删除指定结点 cout<<"删除一个结点!\n"; } head=headtemp; } return head; //返回链表头指针

} 插入结点: node * Insert(node * head, node *pn) { node *pc,*pa; //定义指向插入点前、后的指针 pc 与 pa pc=pa=head; if (head==0) //若链表为空,则新结点插入到链表首 { head=pn; pn->next=0; return head; } if (pn->score>=head->score) //若新结点成绩≥首结点成绩则新结点插在链首 { pn->next=head; head=pn; return head; } while (pc->next!=0 &&pn->score<=pc->score) //若链表非空,则按成绩查找插入点 { pa=pc; // pc、pa 移到插入点前、后结点处 pc=pc->next; } if (pn->score <= pc->score) //新结点插入到链尾 { pc->next=pn; pn->next=0; } else //新结点插入到链表中间 { pn->next=pc; pa->next=pn; } return head; //返回链表头指针 } 建立一条有序链表: node *Create_sort( void) { node *pn,*head=0; //定义指向新结点的指针变量 pn 及链表头指针 head int score; //定义输入学生成绩的临时变量 score char name[8]; //定义输入学生姓名的临时变量 name[8] cout<<"产生一条有序链表,请输入数据,以-1 结束!\n"; cin>>score; //输入学生成绩 while (score!= -1) //成绩不等于-1 则循环 { pn=new node; //动态分配 node 类型结点空间,并将其地址赋给 pn cin>>name; //输入学生姓名 strcpy(pn->name,name); //学生姓名、成绩拷贝到结点 name、score 字段中 pn->score=score; head=Insert(head,pn); //调用结点插入函数,将新结点按成绩降序插入链表 cin>>score; //输入学生成绩 } return head; //返回链表头指针 }

主程序: # include <iostream.h> # include <string.h> void main(void) //主函数 { node * head; char name[8]; head=Create(); //产生无序链表 Print(head); //输出无序链表 cout<<"输入要删除结点上学生姓名:\n"; cin>>name; //输入要删除结点的学生姓名 head=Delete(head,name); //删除指定姓名的结点 Print(head); //输出显示删除后的链表。 Delchain(head); //删除整个链表 head=Create_sort(); //产生一个有序链表 Print (head); //输出显示有序链表 Delchain(head); //删除整个链表 } 运行结果: 产生无序链表,请输入学生成绩与姓名,以-1 为结束: 90 Zhang 80 Li 70 Wang -1 输出链表中各结点值: Zhang 90 Li 80 Wang 70 输入要删除结点上学生姓名: Li 删除一个结点! 输出链表中各结点值: Zhang 90 Wang 70 产生一条有序链表,请输入数据,以-1 结束! 90 Zhang 80 Li 85 Wang 95 Zhou -1 输出链表中各结点值: Zhou 95 Zhang 90 Wang 85 Li 80

(二)完成实验项目
1.定义一个学生成绩结构体类型,包含“学号” 、 “姓名” 、 “性别” 、 “年龄” 、 “班级” 、 “英语” 、 “数学” 、 “物理” 、 “总分” 、 “名次”等信息。编写 6 个函数分别用于: (1) 使用结构体数组,输入全班 10 名学生的上述信息; (2) 计算每一个学生的总分、平均分; (3) 计算每一门课程的平均分; (4) 查找成绩有不及格的学生信息; (5) 按学生成绩总分降序排序;

(6) 输出全班学生的学号、总分及名次。 2.利用上一题的结构类型,创建包含 10 个结点的无序链表。编写 5 个函数分别实现下 述功能(参考前面第三部分内容) : (1) 显示链表; (2) 添加结点; (3) 删除结点; (4) 计算每位学生的总分; (5) 按英语成绩排序。

四、课后作业
撰写实验报告。

五、实验机时
2 个标准学时。 #include <iostream> using namespace std; #define N 10 //定义 N,代表 10 名学生 structstu_score { intnum; //学号 char name[10]; //姓名 char sex[5]; //性别 int age; //年龄 int classes; //班级 float english; //英语 float math; //数学 float physics; //物理 float sum; //总分 float avg; //平均分 intmingci; //名次 }; void putinfor(stu_score score[]); //输入全班 10 名学生的上述信息 void sum_avg(structstu_score score[]); //计算每一名学生总分平均分 void course_avg(structstu_score score[]); //计算每一门课程的平均分 void findstu(structstu_score score[]); //查找成绩有不及格的学生信息 void sequence(structstu_score score[]); //按学生成绩总分降序排序 void display(structstu_score score[]); //输出全班学生的学号、总分及名次 int main() { structstu_scorestu[N]; putinfor(stu); sum_avg(stu); course_avg(stu); findstu(stu); sequence(stu); display(stu); //主函数调用六个子涵数

return 0; } voidputinfor(stu_score score[]) { for(inti=0;i<N;i++) { cout<<"请输入第"<<i+1<<"个学生的信息:"<<endl; cout<<"姓名:"; gets(score[i].name); cout<<"性别:"; gets(score[i].sex); cout<<"学号:"; cin>>score[i].num; cout<<"年龄:"; cin>>score[i].age; cout<<"班级:"; cin>>score[i].classes; cout<<"英语成绩:"; cin>>score[i].english; cout<<"数学成绩:"; cin>>score[i].math; cout<<"物理成绩:"; cin>>score[i].physics; } } voidsum_avg(structstu_score score[]) { for(inti=0;i<N;i++) { score[i].sum=score[i].english+score[i].math+score[i].physics; score[i].avg=score[i].sum/3; } } voidcourse_avg(structstu_score score[]) { floateng_avg,math_avg,phy_avg; floateng_sum=0,math_sum=0,phy_sum=0; for(inti=0;i<N;i++) { eng_sum=eng_sum+score[i].english; math_sum=math_sum+score[i].math; phy_sum=phy_sum+score[i].physics; }

eng_avg=eng_sum/N; math_avg=math_sum/N; phy_avg=phy_sum/N; cout<<"英语的平均分为:"<<eng_avg<<endl; cout<<"数学的平均分为:"<<math_avg<<endl; cout<<"物理的平均分为:"<<phy_avg<<endl; } voidfindstu(structstu_score score[]) { for(inti=0;i<N;i++) { if(score[i].english<60||score[i].math<60||score[i].physics<60) { cout<<"第"<<i+1<<"个学生有不及格课程学号为: "<<score[i].num<<" "<<"姓名 为:"<<score[i].name<<endl; } } } void sequence(structstu_score score[]) { structstu_score temp; //定义一个缓存数组 for(inti=0;i<N-1;i++) //冒泡法对学生总成绩进行降序排序 { for(int j=i+1;j<N;j++) { if(score[i].sum<score[j].sum) //比较的是总分 { temp=score[i]; //交换的是结构数组 score[i]=score[j]; score[j]=temp; } } } for(i=0;i<N;i++) //交换完成的结构数组是按总分的降序排列 { score[i].mingci=i+1; } } void display(structstu_score score[]) { cout<<"全班学生的学号、总分、名次如下:"<<endl; cout<<"学号 总分名次:"<<endl; for(inti=0;i<N;i++)

{ cout<<score[i].num<<" } } "<<score[i].sum<<" "<<score[i].mingci<<endl;


相关文章:
C语言第五章习题答案
建议用结构体完成,可参考 P204【例 7-2】。 输入: 输出: 输入样例: 输出...创建链表时输入 5 个职工的职工号工资,学号为大于 100 且小于 200 的 输入...
结构体和共用体 参考答案
结构体和共用体 参考答案 - 实验八 班级: 结构体及其应用 姓名: 成绩: 学号: 一. 实验目的 1、掌握结构体数据类型的定义和使用。 2、掌握结构体数组的定义和...
实验八 构造数据类型
实验八 构造数据类型 - 实验八 构造数据类型 一、实验学时 4 学时。 二、实验目的 1.掌握结构体类型变量和结构体类型指针的定义和使用。 2.掌握结构体类型...
第10章 结构体与共用体
第10 章 结构体与共用体 考核知识点 ● 结构体与共用体类型数据的定义方法和引用方法 ● 用指针和结构体构成链表,单向链表的建立、输出、插入与删除 重要考点 ...
10结构体与共用体(1)
4.已知 head 指向一个带头结点的单向链表,链表中每个结点包含字符型数据域(data...实验10 结构体与共用体 7页 免费 第10章结构体与共用体 4页 免费 十、...
更多相关标签: