C语言程序设计课件第12章

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
间,然后将该结点通过修改特定结点的指针域插入链表中
单链表的删除:从单链表中删除指定值的结点
• 首先要用遍历的思想查找该值的结点是否在单链表存在 • 一定要有一个指向待删除结点前趋结点位置的指针以便删除
2020/1/29
尾 插
演示
过 程
序 插
演示
过10 删 程除
演示
过 程
单链表
单链表的逆置:将原单链表中各结点的指向关系置反
• (2)用指针可以申请动态数组,空间不会浪费或不足,但仍 然是需要连续的存储空间
• (3)在数组中插入或删除元素时需要大量移动元素,效率低
什么是链表结构?
• 与数组不同,数组元素逻辑上相邻物理地址上也相邻,而链 表结构其数据元素作为一个个结点的数据域,结点中另有指 针域存储逻辑上相邻的其他元素的起始地址,单链表较常用
• ④ 如何能做到便于操作,即人机接口的界面友好,方便使用 者的操作。
2020/1/29
15
学生成绩档案管理系统的
设计与实现
数据类型的定义: 用结构类型表示每个学生的信息
• struct Student
•{
long num;

char name[20];

char sex[10];

int score[3];
• 原来的前趋变后继 • 原来的第一个结点变成最后一个结请点在VC++下运行完 • 原来的最后一个结点变成第一个结整点程序进行演示 • 并且所有相邻结点的指向关系都要置反
单链表的完整操作:完整程序由4个文件组成:
• (1)node.h:定义链表结点的类型,Type代表结点的数据域类型 • (2)prepare.h:定义结点的数据成员类型中需要的一些基本操
容读出置于单链表中 • void saveFile(struct node *head):将链表中各结点的值依
次写入文件
2020/1/29
17
学生成绩档案管理系统的 设计与实现
完整的程序用两级菜单四层多个函数5个文件实现:
• ① 修改后的node.h(见12.2.1节) • ② 修改后的prepare.h(见12.2.2节) • ③file.h(见12.2.3节) • ④list.h(见12.1.8节的第3个文件,无需改动) • ⑤li12_2.c,系统实现的最主要文件

int total;

int rank;
• };
• typedef struct Student Type;
存储结构的选择:一维数组还是单链表?
• 无论从内存空间的使用效率上,还是操作的便捷程度上,单
链表结构要优于数组结构,以Type为结点的数据域类型
2020/1/29
16
学生成绩档案管理系统的 设计与实现
• 这种插入方法无需定义tail指向最后一个结点,代码最简洁
方法3:按序插入法的关键是:
• 首先要通过搜索找到新结点的插入位置,这在后面有序插入 算法中介绍
• 假设找到的插入位置是在p1指针所指的结点后,在p2指针所 指的结点前插入
• 则关键的语句为:p1->next=p; 和 p->next=p2;
作,从而保证无论Type代表何种类型,链表的基本操作不变 • (3)list.h:定义了单链表的各种操作,包括用3种方法建立链
表、插入、删除、查找、遍历、逆置等基本操作 • (4)li12_1.c:测试单链表各种应用的完整程序,包含了以上
3个文件,其中定义了菜单函数,运行函数和主函数
2020/1/29
2020/1/29
8
动 态
演示
过 程
单链表
单链表的遍历:从头指针开始,顺着各个指针,依次访
问链表中的各个结点
• 关键是确定遍历的条件,即何时循环,何时终止
• 根据单链该表函的数最是后根一据个结指点针域为空,可以让一个工作指针指向
当前结点的,不数断据后域移类,型如定果义该指针为空,则链表遍历结束
• 关键代码:
• while(p&&!equal(p->data,data,1))

p=p->next;
2020/1/29
9
动 态
演示
过 程
单链表
单链表的插入:向一个单链表中插入以给定值为数据域 信息的结点。
常见的插入方法有两种:
• ①直接在链表尾部插入 • ②依照数据域的值有序(非递减有序或非递增有序)插入 • 无论哪一种方法的插入,都需要通过指针申请一个新结点空
11
逆 置
演示
过 程
其他类型的单链表
(1)单循环链表:
• 为什么要循环:单链表如果丢失了头指针则无法访问链表 • 改进方法:将单链表最后一个结点的指针域由空指针改为指
向链表的第一个结点形成一个循环链 • 好处:从任意一个结点位置开始均可以遍历整个单链表 • 变化:用遍历思想进行访问时链表结束的终止条件不是
C语言程序设计
1
2020/1/29
第十二章 高级程序设计
主讲: 计算机学院 朱立华
2
2020/1/29
内容提要
本章介绍单链表的相关知识以及一个管理系统的模块化 设计方法, 综合运用所学知识实现一个完整的系统
关于单链表掌握以下知识:
• 为什么需要单链表 • 如何通过指针和结构体的定义实现单链表结构 • 单链表常用操作的实现方法:建立、遍历、插入、删除、查找、
2ቤተ መጻሕፍቲ ባይዱ20/1/29
12
其他类型的单链表
(3)带表头结点的单循环链表:
• 改进方法:将前两种结合起来,既带表头结点又将最后一个
结点的指针域指向头结点处
• 好处:既解决了丢失头指针无法访问整个链表的问题,又解
决了插入、删除操作时的便利性问题。
• 变化:在编程时,进行插入和删除操作时无需考虑是否在第
p插入链表之后,要做赋值: tail=p; 以后通过tail->next=p;就 可以实现在尾部插入新结点
2020/1/29
7
动 态
演示
过 程
单链表
方法2:前插法的关键是:
动 态
演示
过 程
• 新结点的指针域值一定赋值为head,成为新的第一个结点
• 头指针每插入一个新结点就要修改一次,保证永远指向新的 第一个结点处
逆置 • 其他类型的链表结构简介
学生档案成绩管理系统的设计与实现:
• 如何划分模块,每一个模块的具体功能是什么 • 数据类型的定义 • 用文件实现数据的永久存储 • 系统的完整实现
2020/1/29
3
单链表
为什么需要链表结构?
• 一批类型相同的数据用数组存储所存在的问题:
• (1)定义静态数组时必须指定数组的元素个数,此后无法更 改数组大小,可能造成空间浪费或不足
• 类比:双链表也可以有带表头的、循环的、带表头的循环
2020/1/29
13
学生成绩档案管理系统的
设计与实现
功能:
• 读入学生信息、以数据文件的形式存储学生信息;可以增加、 修改、删除学生的信息;按学号、姓名、名次查询学生信息; 可以依学号顺序浏览学生信息;可以统计每门课的最高分、 最低分以及平均分;计算每个学生的总分并排名。
一个元素结点前面插入,同时遍历链表结束的条件不是
p==NULL,而是p在向后移动过一次以后,再一次满足p==head
引申:双链表(选讲)
• 区别:如果一个链表中各个结点的指针域有两个,分别指向
其直接前趋和直接后继,就成为双向链表,第一个结点指向前
趋的指针和最后一个结点指向后继的指针均为空指针
• 变化:在插入和删除时需要修改的指针数量比单链表要加倍
typedef int Type;
struct Node {
结点的数据成员名data, 结类点型的为指Ty针pe成员名next,类 型为struct Node*

Type data;

struct Node *next;
};
特别提醒:next前的*号不能丢失,否则就成为死循环定义啦!
用结构化程序设计的思想,将系统分成5大功能模块:
• 显示基本信息
• 基本信息管理: 插入、删除、修改学生记录3个子模块
• 学生成绩管理:计算学生总分、根据总分排名两个子模块
• 考试成绩统计:求课程最高分、最低分、平均分3个子模块
• 根据条件查询:根据学号、姓名、名次查询3个子模块
2020/1/29
2020/1/29
数据域
4
指针域
单链表的 一个结点
单链表
这是最重要
一个单的链头表指示针例:
最后一个结点的指 针域值为0(NULL)
1
2
3
40

链表结构的优点是:
• 系统不必为应用程序分配一组连续的空间,可以充分利用系 统的零散空间;有一个元素就生成一个结点,空间不浪费
• 如果内存空间足够大,理论上这一批数据的容量不受限制
(一)单链表的建立:
• 常用的有3种建立方法: • 后插法:新结点插入在链表的最尾部,作为新的尾结点 • 前插法:新结点插入在链表的最前部,作为新的第一个结点 • 按序插入法:新结点插入在链表的特定部位保持元素值有序
2020/1/29
6
单链表
无论是哪一种建立方法,共同的操作是:
• 最主要的是指向第一个结点的头指针,有时需要设一个指向 最后一个结点的尾指针以方便操作,注意头指针该如何修改
在VC++下运行程序进行演示
2020/1/29
18
本章小结
本章主要介绍了单链表的各种操作及一个管理系统 的实现。
关于单链表:
• (1)如何用指针和结构体递归定义形成单链表,对单链 表的各种操作:建立、遍历、插入、删除、查找、逆置等 方法进行了详细介绍并用完整的代码实现
• (2)强调代码重用思想,对结点的数据类型用自定义类 型标识符Type来表示,定义特定的基本操作,从而保证了 单链表各种操作的实现函数的代码的通用性
• 逐个申请结点空间 • 对每个结点的数据域赋值 • 每个结点的指针域如何赋值取决于建立方法 • 将新结点加入到链表中,即修改链表中某一个结点的指针域
方法1:后插法的关键是:
• 新结点的指针域值一定为空,因为它是新的最后一个结点 • 头指针只要修改一次,即在空链状态下插入第一个点时修改 • 保证tail指针始终指在当前链表的最后一个结点处,即新结点
• 对于插入、删除等操作不必通过移动元素实现,效率高
单链表的结点定义----用结构体和指针递归定义而成
2020/1/29
5
单链表 单链表结点用的T数yp据e作成为员类类型型别不名同,只使需结要点将类int替换成数
据成员实际型的的类定型义,具下有面更结好点的的通类用型性定义不变
单链表结点定结义点的的格结式构:体类型定义
14
学生成绩档案管理系统的 设计与实现
为实现该系统,需要解决以下问题:
• ① 数据的表示,用什么样的数据类型能正确、合理、全面地 表示学生的信息,每个学生必须要有哪些信息。
• ② 数据的存储,用什么样的结构存储学生的信息,有利于可 扩充性并方便操作。
• ③ 数据的永久保存问题,数据以怎样的形式保存在磁盘上, 避免数据的重复录入。
为直接使用list.h中定义的各种单链表操作的函数,需 要对node.h和prepare.h两个文件中的内容作相应改造
文件的选择:用二进制文件存储学生的信息
• 在file.h中定义3个主要的函数: • void createFile( ):建立初始的数据文件 • struct node * readFile(struct node *head):将文件中的内
• 关键代码的: 一个输出函数
• for(p = head; p; p = p->next) • printNode(p->data);
动 态
演示
过 程
单链表的查找:在该单函链数表是中根搜据索结点是的否数存据在这样的结点,
其数据域或数据域域的类某型一定项义等的于一给个判定断待元搜索的值。
• 查找返回:若存在则素返值回是指否向相该等结的点函的数指针,否则返回空指针
p==NULL而是p在向后移动过一次以后,再一次满足p==head。
(2)带表头结点的单链表:
• 为什么要带表头:单链表中插入或删除一个结点时一定要考 虑是否需要修改头指针,操作不方便
• 改进方法:在单链表真正的第一个结点前面增加一个附加结 点,其数据域通常不放什么有用信息,该结点称为表头结点
• 好处:插入或删除时无需考虑修改头指针的问题 • 变化:用遍历思想访问时终止条件不变但多1次指针的移动
• (3)单链表的定义与实现过程中可能会用到C语言的所有 知识:基本数据类型、自定义类型,为实现各种操作,需 要运用函数的定义与调用、流程控制、动态结点空间的申 请与释放、递归思想等
2020/1/29
19
本章小结
关于学生成绩档案管理系统:
• (1)如何用模块化程序设计思想对系统的功能进行合理 划分,再用相应的函数对应实现相关功能
相关文档
最新文档