程序设计导引及在线实践

Page 217

在程序中,一个链表有了“表头”之后,可以被当作一个带有指针域的普通结构型变量。 这个指针指向链表的首结点。在程序中要向链表中插入新结点、查找或删除符合某个条件的 结点、对链表的结点进行排序时,都通过链表的表头获得首结点的地址、以及其他有用的信 息。链表的结点数据类型、表头数据类型需要分别定义。定义了链表结点的数据类型后,再 定义链表表头的数据类型。 下面的程序是建立、使用带表头单向链表的示例。这个例子与上一节的例子基本相同, 只是增加了链表的查找功能、并使用了表头。先输入一组学生的学号、姓名和课程成绩。当 输入的成绩为负数时,表示输入结束。程序将输入的数据存储在一个带表头的单向链表中。 然后计算并输出全部学生的平均成绩、查找并输出成绩不及格的学生。 程序的第 4~11 行首先定义了链表结点的数据类型。第 12~20 行定义了一个链表表头的 数据类型。其中第 13~17 行是表头的数据域部分,可以根据程序的需要定义任意的结构成员, 也可以没有。在本程序中,共定义了三个成员:totalStudents、totalScore、unqualifiedStudents。 totalStudents 用来记录链表中学生的总数,也是链表的长度。totalScore 记录链表中各个学生 的成绩总和,目的是方便统计平均成绩。unqualifiedStudents 记录链表中不及格学生的人数, 用于成绩不及格学生的输出。第 18 行定义表头的指针域,是指向链表第一个结点的指针。 在定义链表表头的数据类型时,一定要有这个结构成员。 程序的第 24 行用所定义的表头数据类型,在主程序中声明了一个结构型变量:link, 代表一个带表头的单向链表。第 28~32 行对链表表头进行初始化。在第 28 行先将 link.head 赋值为 NULL,表示一个结点也没有。然后对表头中的其它成员变量分别赋初始值。 在程序的 35~55 行是建立链表的过程。每次总是先创建一个结点,然后将新的结点添加 在 link.head 所指向的链表的末尾;并修改表头数据域部分的各个分量值。 程序的 58~59 行是使用链表统计、输出学生的平均成绩。由于在表头中已经记录了学生 的总人数、他们的成绩之和,在计算平均成绩时就不再需要访问链表中的结点,只要使用表 头中记录的信息就可以了。 程序的第 62~68 行搜索并输出成绩不及格学生的名单。在输出这些学生的姓名和学号之 前,先根据表头所记录的信息输出不及格学生的总数,这样程序的输出信息更直接、更容易 被理解。在搜索不及格学生的名单时,先从表头中得到链表第一个结点的地址,然后依次比 较每个结点中的学生成绩,直到链表的末尾。 第 71~75 行在程序结束之前,释放链表结点占用的存储空间。每次删除链表中排在最前 面的一个结点,剩余部分的地址仍然记录在表头中。 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.

#include <stdio.h> struct Student {//定义链表节点的结构 //数据域部分:记录链表元素的值 char ID[20]; char name[50]; float score; //指针域部分:指向链表的下一个节点 Student *next; }; struct StudentList {//定义链表表头的结构 215


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.