C语言链表详解ppt教学文稿

上传人:go****e 文档编号:137376065 上传时间:2020-07-07 格式:PPT 页数:91 大小:890.50KB
返回 下载 相关 举报
C语言链表详解ppt教学文稿_第1页
第1页 / 共91页
C语言链表详解ppt教学文稿_第2页
第2页 / 共91页
C语言链表详解ppt教学文稿_第3页
第3页 / 共91页
C语言链表详解ppt教学文稿_第4页
第4页 / 共91页
C语言链表详解ppt教学文稿_第5页
第5页 / 共91页
点击查看更多>>
资源描述

《C语言链表详解ppt教学文稿》由会员分享,可在线阅读,更多相关《C语言链表详解ppt教学文稿(91页珍藏版)》请在金锄头文库上搜索。

1、1,第十一章 链表 链表详解 珍藏版,2,例:跳马。依下图将每一步跳马之后的位置(x,y)放到一个“结点”里,再用“链子穿起来”,形成一条链,相邻两结点间用一个指针将两者连到一起。,结构的概念与应用,3,依上图有7个结点,为了表示这种既有数据又有指针的情况,引入结构这种数据类型。,4,11.7 用指针处理链表,链表是程序设计中一种重要的动态数据结构,它是动态地进行存储分配的一种结构。,动态性体现为: 链表中的元素个数可以根据需要增加和减少,不像数组,在声明之后就固定不变; 元素的位置可以变化,即可以从某个位置删除,然后再插入到一个新的地方;,5,1、链表中的元素称为“结点”,每个结点包括两个域

2、:数据域和指针域; 2、单向链表通常由一个头指针(head),用于指向链表头; 3、单向链表有一个尾结点,该结点的指针部分指向一个空结点(NULL) 。,Head 1249 1356 1475 1021,结点里的指针是存放下一个结点的地址,6,链表中结点的定义,链表是由结点构成的, 关键是定义结点; 链表的结点定义打破了先定义再使用的限制,即可以用自己定义自己; 递归函数的定义也违反了先定义再使用; 这是C语言程序设计上的两大特例,7,链表的基本操作,对链表的基本操作有: (1)创建链表是指,从无到有地建立起一个链表,即往空链表中依次插入若干结点,并保持结点之间的前驱和后继关系。 (2)检索操

3、作是指,按给定的结点索引号或检索条件,查找某个结点。如果找到指定的结点,则称为检索成功;否则,称为检索失败。 (3)插入操作是指,在结点ki-1与ki之间插入一个新的结点k,使线性表的长度增1,且ki-1与ki的逻辑关系发生如下变化: 插入前,ki-1是ki的前驱,ki是ki-1的后继;插入后,新插入的结点k成为ki-1的后继、ki的前驱.,8,(4)删除操作是指,删除结点ki,使线性表的长度减1,且ki-1、ki和ki+1之间的逻辑关系发生如下变化: 删除前,ki是ki+1的前驱、ki-1的后继;删除后,ki-1成为ki+1的前驱,ki+1成为ki-1的后继. (5)打印输出,9,一个指针类

4、型的成员既可指向其它类型的结构体数据,也可以指向自己所在的结构体类型的数据,num Score next,next是struct student类型中的一个成员,它又指向struct student类型的数据。 换名话说:next存放下一个结点的地址,10,11.7.2 简单链表,#define NULL 0 struct student long num; float score; struct student *next; ; main() struct student a, b, c, *head, *p; a.num=99101; a.score=89.5; b. num=99103;

5、 b.score=90; c.num=99107 ; c.score=85; head= ,例11.7,建立和输出一个简单链表,各结点在程序中定义,不是临时开辟的,始终占有内容不放,这种链表称为“静态链表”,11,11.7.3 处理动态链表所需的函数,C 语言使用系统函数动态开辟和释放存储单元,1.malloc 函数,函数原形:void *malloc(unsigned int size); 作用:在内存的动态存储区中分配 一个 长度为size的连续空间。 返回值:是一个指向分配域起始地址的指针(基本类型void)。 执行失败:返回NULL,12,函数原形:void *calloc(unsig

6、ned n,unsigned size); 作用:在内存动态区中分配 n个 长度为size的连续空间。 函数返回值:指向分配域起始地址的指针 执行失败:返回null 主要用途:为一维数组开辟动态存储空间。n 为数组元素个数,每个元素长度为size,2. calloc 函数,13,3. free 函数,函数原形: void free(void *p); 作用:释放由 p 指向的内存区。 P:是最近一次调用 calloc 或 malloc 函数时返回的值。 free 函数无返回值 动态分配的存储单元在用完后一定要释放,否则内存会因申请空间过多引起资源不足而出现故障。,14,结点的动态分配,ANSI

7、 C 的三个函数(头文件 malloc.h) void *malloc(unsigned int size) void *calloc(unsigned n, unsigned size) void free(void *p) C+ 的两个函数 new 类型(初值) delete 指针变量 /* 表示释放数组,可有可无)*/ 使用 new 的优点: 可以通过对象的大小直接分配,而不管对象的具体长度是多少(p340 例14.10),15,11.7.4 建立动态链表,基本方法: 三个结点(头结点head、尾结点 NULL 和待插入结点 P) 第一步:定义头结点head、尾结点 p2 和待插入结点p

8、1,待插入的结点数据部分初始化; 第二步:该结点被头结点、尾结点同时指向。P1=p2=(struct student*)malloc(LEN);头指针部分为空,head=NULL; 第三步:重复申请待插入结点空间,对该结点的数据部分赋值(或输入值),将该结点插入在最前面,或者最后面(书上在尾部插入). P2-next=P1; P2=P1; 最后:P2-next=NULL;,*head,*p1,*p2,使用malloc(LEN),P2-next=NULL;,16,11.7.4 建立动态链表,head,P1 p2,1.任务是开辟结点和输入数据 2.并建立前后相链的关系,待插入的结点p1数据部分初始

9、化,该结点被头结点head、尾结点p2同时指向.,17,图11.14,head,p2,p1,head,p2,p1,(a),(b),p1重复申请待插入结点空间,对该结点的数据部分赋值(或输入值),P2-next 指向p1新开辟的结点。,18,图11.14,head,p1,p2,(c),P2指向新结点p2=p1,19,图11.15,p2,p1,head,p2,p1,head,(a),(b),20,图11.16,p2,p1,head,p2,p1,head,21,例11.8 建立一个有3名学生数据的单向动态链表,#define NULL 0 #define LEN sizeof(struct stud

10、ent) struct student long num; float score; struct student *next; ; int n; struct student *creat(void) struct student *head; struct student*p1,*p2; n=0; p1=p2=(struct student*) malloc(LEN); scanf(%1d,%f,结构体类型数据的长度,sizeof是“字节数运算符”,定义指针类型的函数。带回链表的起始地址,开辟长度为LEN的内存区,P1,p2是指向结构体类型数据的指针变量,强行转换成结构体类型,假设头指向空

11、结点,22,续,while(p1-num!=0) n=n+1; /*n 是结点的个数*/ if(n=1)head=p1; else p2-next=p1; p2=p1; p1=(struct student*)malloc(LEN); scanf(%1d,%f, /返回链表的头指针,算法:p1指向新开的结点: p1=(stuct student*)malloc(LEN); p1的所指向的结点连接在p2所指向结点后面,用p2-next=p1来实现。 p2 指向链表中最后建立的结点,: p2=p1;,头指针指向p1结点,P1开辟的新结点链到了p2的后面,P1继续开辟新结点,给新结点赋值此,23,1

12、1.7.5 输出链表,链表遍历 1.单向链表总是从头结点开始的; 2.每访问一个结点,就将当前指针向该结点的下一个结点移动: p=p-next; 3.直至下一结点为空 P=NULL,24,图 11.18,head,p,P,P,25,例题 9,void print (struct student *head) struct student * p; printf(nNow,These %d records are:n,n); p=head; if(head!=NULL) do printf(%ld %5.lfn,p - num,p - score); p=p - next; while(p!=N

13、ULL); ,26,11.7.6 对链表的删除操作,删除结点原则: 不改变原来的排列顺序,只是从链表中分离开来,撤消原来的链接关系。 两种情况: 1、要删的结点是头指针所指的结点则直接操作; 2、不是头结点,要依次往下找。 另外要考虑:空表和找不到要删除的结点,27,链表中结点删除,需要由两个临时指针: P1: 判断指向的结点是不是要删除的结点(用于寻找); P2: 始终指向P1的前面一个结点;,28,图11.19,(a),(B),29,图11.20,head,p1,(a),(b),head,p2,p1,原链表 P1指向头结点,P2指向p1指向的结点。P1指向下移一个结点。,30,图11.20

14、,head,p1,head,p2,p1,(c),(d),经判断后,第1个结点是要删除的结点,head指向第2个结点,第1个结点脱离。,经P1找到要删除的结点后使之脱离。,31,例 题 10,struct student *del( struct student *head, long num ) struct student *p1, *p2; if(head=NULL) printf(nlist null!n); goto end; p1=head; while(num!=p1-num ,找到了,没找到,32,11.7.7 对链表的插入操作,插入结点:将一个结点插入到已有的链表中 插入原则:

15、 1、插入操作不应破坏原链接关系 2、插入的结点应该在它该在的位置 实现方法: 应该有一个插入位置的查找子过程 共有三种情况: 1、插入的结最小 2、插入的结点最大 3、插入的结在中间,33,操 作 分 析,同删除一样,需要几个临时指针: P0: 指向待插的结点;初始化:p0=数组stu; P1: 指向要在P1之前插入结点;初始化: p1=head; P2: 指向要在P2之后插入结点; 插入操作:当符合以下条件时:p0-num 与 p1-num 比较找位置 if(p0-nump1-num),34,图11.22,head,p1,(a),p0,35,图11.22,p1,(b),36,例 题 11,

16、struct student insert(struct student *head,struct student *stud) struct student *p0,*p1,*p2; p1=head; p0=stud; if( head=NULL; ) head=p0;p0-next=NULL; else while( p0-nump1-num) ,原来的链表是空表,P0指向要插的结点,使p0指向的结点作为头结点,使p2指向刚才p1指向的结点,插到原来第一个结点之前,插到p2指向的结点之后,插到最后的结点之后,链接,37,head,课堂举例:已有一个如图所示的链表; 它是按结点中的整数域从小到大排序的,现在要插入一个结点,该结点中的数为10,待插入结点,此结点已插入链表,38,分析:按三种情况 1、第一种情况,链表还未建成(空链表),待插入结点p实际上是第一个结点。这时必然有head=null。只要让头指针指向 p 就可以了。语句为,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 幼儿/小学教育 > 其它小学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号