C语言程序设计PPT

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
p->next=r->next; 点*/ r->next=p; /*将*r的指针域指向*p*/ /*将*p的指针域指向*r的下一个结

说明:在链表中插入新结点并不需要移动链表中的元素,
只需要修改指针的指向即可。
15.2 链表的操作
15.2.5 链表的删除操作

删除链表中元素值为’a’的结点,操作过程如图15.8所示。
15.1 链表的相关概念

函数malloc常常与运算符sizeof配合使用。例如,要分配
一个大小为40的int型的内存空间,代码如下:

int *p; p=(int*)malloc(sizeof(int)*40);
15.1 链表的相关概念

2。free函数──动态内存释放函数
函数free的主要作用是将动态分配的内存空间释放。它的 函数原型如下: void free(void *p);
r->next=p->next; /*删除p指向的结点,使*p脱链*/ free(p); /*释放p指向的结点的内存空间*/
15.2 链表的操作
15.2.6 链表的应用举例——学生信息管理系统 【例15.2】建立一个学生信息管理系统,管理系统有一 个目录菜单,包括6个选项: 1.建立学生信息链表 2.插入一名新的学生 3.从链表中删除学生 4.在链表中查找学生; 5.在链表中浏览信息; 6.退出程序结束操作 根据需要选择其中一项,来实现链表的创建、结点插 入、信息查找、删除结点、浏览信息、退出功能。学 生信息包括学号和姓名。
15.1 链表的相关概念
struct student /*定义结点类型*/ { char data; /*数据域*/ struct student *next; /*next是指针域,指向结 构体类型struct student*/ };

其中,指针域是一个指向struct student的结构体指针类 型。我们将这种存在指针指向自己的结构体类型称为自 引用类型。
r->next=p->next,使p指向的结点 脱链,即删除*p结点
feee(p),释放p指向的结点内存空间
15.2 链表的操作

删除元素值为’a’的结点的关键代码如下:
r=findnode2(h,’a’); /*查找要删除的结点,返回
值r指向要删除结点的前一个结点*/ p=r->next; /*p指向要删除的结点*/
};
15.1 链表的相关概念

这种结点构成的链表如图15.3所示。
head 101 zhang beijing 102 yang henan 103 chen wuhan 104 xu hunan NULL 学号 姓名 地址
15.1 链表的相关概念


15.1.2 动态存储分配 链表中的结点是动态存储分配的,而不是由系统自动分配 的。动态存储分配是在使用前才进行分配内存空间,使用 完毕就可以释放内存空间。内存空间的分配和释放由用户 自己决定。 1。malloc函数──动态内存分配函数 函数malloc的主要作用是分配一块长度为size的内存空间。 函数原型如下: void *malloc(unsigned int size);
第10章 指针

15.2 链表的相关概念
15.2 链表的操作

15.2 链表的相关概念

链表是由一个个结点顺序连接起来构成的表,称为链表。
其中,结点用来存放元素信息和下一个元素的地址。链表 中的元素在逻辑上相邻,在物理上不一定相邻。而数组中 的元素逻辑上相邻,在物理上也一定相邻。本节主要讲解 链表的基本概念和动态内存分配。

链表的输出就是将链表中的各个结点的数据依次输出。输
出链表的操作非常简单,定义一个指针变量p,使其指向
链表的第一个结点。然后输出p指向的结点,并让p指向下
一个结点。依次类推,直到输出所有结点的元素。
15.2 链表的操作

输出链表的函数如下:
void displist(struct node *h) {
15.2 链表的操作

插入第二个结点的过程如图15.5所示。
head q head q p head ‘Y’ p ‘X’ q
‘X’ p
‘Y’
‘X’
‘Y’
(1)生成一个结点,并 将’Y’存放到该结点
(2)令q指向p指向的结 点,即q->next=p
(3)令q指向最后一个结 点,即q=p
15.2 链表的操作
动态生成结点。
15.2.1 链表的创建




输入结点的数据。
将结点连接在一起。
15.2 链表的操作

例如,要将3个字符’X’、’Y’和’Z’依次存放到结点中, 构成一般链表。需要先定义一个结点类型,代码如下:
struct node
{
char ch; struct node *next; }ListNode;
15.3 小结

使用链表有两个好处:不需要像数组一样事先分配存
储单元,不必担心空间定义过小无法适应程序的需要, 也不必担心定义过大造成空间浪费;在插入和删除操
作过程中,不需要移动大量的元素。

链表是一种顺序存取的结构,因此,要访问链表中的 某个结点,必须从头指针开始。
r ‘Y’ ‘Z’
NULL
p ‘a’
p ‘a’
(1)生成新结点*p r ‘X’ ‘Y’ ‘Z’
NULL
(2)找到要插入的位置 r ‘X’ ‘Y’ ‘Z’
NULL
head
head
p ‘a’
p->next=r->next
p ‘a’ r->next=p
(3)将*p插入到链表中
15.2 链表的操作

将新结点插入到*r之后需要两步操作,代码如下:
15.2 链表的操作


15.2.4 链表的插入操作
链表的插入操作是在链表中指定位置插入一个新结点。要将 一个结点插入到链表中,需要解决以下两个问题:

(1)查找插入点。 (2)将新结点插入到链表中。
15.2 链表的操作

插入过程如图15.7所示。
head ‘X’ ‘Y’ ‘Z’
NULL
head ‘X’
15.2 链表的操作

1.将第一个字符’X’插入到链表中 先动态生成一个结点,用p指向该结点。代码如下: p=(ListNode*)malloc(sizeof(ListNode)); 然后将’X’存放到结点的数据域ch中,代码如下: p->ch=’X’; 让头指针head指向第一个结点,代码如下: head=p;
head ‘X’ r ‘Y’ ‘a’ ‘Z’
NULL
head ‘X’r ‘Y’来自p ‘a’ ‘Z’NULL
r=findnode2(h,’a’),r指向要删除结点的前一个结点
p=r->next,p指向要删除的结点
head ‘X’
r ‘Y’
p ‘a’ ‘Z’
NULL
head ‘X’
r ‘Y’ ‘Z’
NULL
15.2 链表的操作

链表的查找操作与链表的输出操作是类似的,只是多
了一个比较的过程。链表的查找操作实现如下:
struct node *findnode(struct node *h,char x) {
struct node *p=h;
while(p!=NULL&&p->ch!=x) p=p->next; return p; }
15.1 链表的相关概念

2.定义链表的结点
链表是由结点构成,结点包括数据域和指针域。一个结 点可以包括一个或多个数据域,因此,需要将结点定义 为结构体类型。因为指针域是指向自身一样的结构体类 型数据,如图15.2中的元素’A’所在结点的指针域指向元 素’B’所在的结点,而’A’和’B’都是同一个类型。
struct node *p=h;
while(p!=NULL) {
printf("%4c",p->ch);
p=p->next; }
}
15.2 链表的操作
15.2.3 链表的查找

链表的查找操作就是在链表中查找指定值的元素,如果找 到,返回该结点的指针,否则返回NULL。链表的查找操 作必须从链表的头指针开始,依次与结点的值进行比较。 直到找到结点或到达链表的末尾,查找操作结束。



3.将第三个字符’Z’插入到链表中 与前两步类似,先动态生成一个结点,并将字符’C’ 存放到该结点,代码如下: p=(ListNode*)malloc(sizeof(ListNode)); p->ch=’Z’; 然后将q指向结点*p,代码如下: q->next=p; 因为p指向的结点是最后一个结点,所以将该结点的 指针域置为NULL。代码如下: p->next=NULL;
15.1 链表的相关概念


15.1.1 链表
1.链表 链表是由结点连接而成,结点就表示一个元素的信息。 链表就是通过地址(指针)将每个结点(元素)连接起 来的表。例如,链表中的元素包括A、B、C、D,如图 15.1所示。
2432 A 2134 2134 B 1256 1256 C 1067 3128 D
这样就将第一个结点的插入到链表中。
15.2 链表的操作

插入第一个结点的过程如图15.4所示。
head p head p q
p
p
‘X’
‘X’
‘X’
(1)生成一个结点
(2)将’X’存放到结点中
(3)head指向第一个结点
(4)q指向第一个结点
15.2 链表的操作



2.将第二个字符’Y’插入到链表中 动态生成一个结点,将字符’Y’存放到该结点中,代码如 下: p=(ListNode*)malloc(sizeof(ListNode)); p->ch=’Y’; 将第2个结点连接在第1个结点之后。代码如下: q->next=p; 让q指向第二个结点,即当前链表的最后一个结点。代码 如下: q=p;

其中,参数p指向要释放的内存空间。函数free没有返回值。
函数原型malloc和free都在头文件stdlib.h和alloc.h中定义。
15.2 链表的操作

链表的主要操作包括:创建链表、输出链表、链表的查 找、链表的插入和链表的删除。 链表的创建就是将一个个结点连接在一起。创建链表的 步骤如下:
15.1 链表的相关概念

在图15.1中,链表由4个结点构成,每个结点包括两个域:
数据域和指针域。数据域用来存放数据信息,指针域表示 地址信息,指向下一个结点的地址。数据域存放的 是’A’、’B’、’C’、’D’。在C语言中,通常用箭头表 示结点之间的先后关系,一个结点的指针指向下一个相邻
的元素。这样利用指针将结点连接起来的表就构成了链表 。
15.1 链表的相关概念

如果要访问链表中的元素,需要先找到第一个结点,为了 找到链表的第一个结点,还需要一个指针指向第一个结点, 我们称这样的指针为头指针,记作head。另外,最后一个 元素’D’的结点没有其它结点,将最后一个结点的指针域 置为NULL。如图15.2所示。
head 2432 2432 A 2134 2134 B 1256 1256 C 1067 3128 D NULL
15.2 链表的操作

插入最后一个结点的过程如图15.6所示。
head ‘X’ head ‘Z’ ‘X’ head ‘Z’ ‘X’
q
‘Y’ p
q
‘Y’
p
q
‘Y’
p
‘Z’ NULL
(1)生成结点,并将’Z’存放到结点中
(2)q->next=p
(3)p->next=NULL
15.2 链表的操作

15.2.2 链表的输出
15.1 链表的相关概念

如果有如下的结构体类型定义:
struct student
{ int no; char name[20]; char addr[30]; /*学号*/ /*姓名*/ /*地址*/
struct student *next; /*next是指向struct student的指针*/
相关文档
最新文档