c语言指针和结构体:链表详解.ppt
《c语言指针和结构体:链表详解.ppt》由会员分享,可在线阅读,更多相关《c语言指针和结构体:链表详解.ppt(91页珍藏版)》请在咨信网上搜索。
1、1第十一章 链表2结构的概念与应用结构的概念与应用3依上图有依上图有7个结点个结点(x1,y1)(x1,y1)(x2,y2)(x2,y2)(x6,y6)(x6,y6)(x7,y7)(x7,y7)411.7 用指针处理链表链表是程序设计中一种重要的动态数据结构,它是动态地进行存储分配的一种结构。动态性体现为:动态性体现为:n链表中的元素个数可以根据需要增加和减少,不链表中的元素个数可以根据需要增加和减少,不像数组,在声明之后就固定不变;像数组,在声明之后就固定不变;n元素的位置可以变化,即可以从某个位置删除,元素的位置可以变化,即可以从某个位置删除,然后再插入到一个新的地方;然后再插入到一个新的
2、地方;512491249 A A13561356 B B14751475 C C10211021 D DNullNull1 1、链表中的元素称为、链表中的元素称为“结点结点”,每个结点包括两,每个结点包括两个域:个域:数据域和指针域;数据域和指针域;2 2、单向链表通常由一个头指针(、单向链表通常由一个头指针(head)head),用于指向,用于指向链表头;链表头;3 3、单向链表有一个尾结点,该结点的指针部分指、单向链表有一个尾结点,该结点的指针部分指向一个空结点向一个空结点(NULL)(NULL)。Head 1249 1356 1475 1021结点里的指针是存放下一个结点的地址6链表中结
3、点的定义q链表是由结点构成的,关键是定义结点;q链表的结点定义打破了先定义再使用的限制,即可以用自己定义自己;q递归函数的定义也违反了先定义再使用;这是C语言程序设计上的两大特例7链表的基本操作对链表的基本操作有:(1)创建链表是指,从无到有地建立起一个链表,即往空链表中依次插入若干结点,并保持结点之间的前驱和后继关系。(2)检索操作是指,按给定的结点索引号或检索条件,查找某个结点。如果找到指定的结点,则称为检索成功;否则,称为检索失败。(3)插入操作是指,在结点ki-1与ki之间插入一个新的结点k,使线性表的长度增1,且ki-1与ki的逻辑关系发生如下变化:插入前,ki-1是ki的前驱,ki
4、是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一个指针类型的成员既可指向其它类型的结构体数据,也可以指向自己所在的结构体类型的数据991019910189.589.59910399103909099107991078585numScorenextnext是是struct student类型中的一个成员,它类型中的一个成员,它又又指向指向
5、struct student类型类型的数据。的数据。换名话说:换名话说:next存放下一个结点的地址存放下一个结点的地址1011.7.2 简单链表#define NULL 0struct 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;b.score=90;c.num=99107;c.score=85;head=&a;a.next=&b;b.next=&c;c.next=NULL;p=head;do
6、 printf(%ld%5.1fn,p-num,p-score);p=p-next;while(p!=NULL);建建立立和和输输出出一一个个简简单单链链表表各结点在程序中定义,不是临时开辟的,各结点在程序中定义,不是临时开辟的,始终占有内容始终占有内容不放不放,这种链表称为,这种链表称为“静静态链表态链表”11 11.7.3 处理动态链表所需的函数C 语言使用系统函数动态开辟和释放存储单元1.malloc 1.malloc 函数函数 函数原形:函数原形:void*malloc(unsigned int size);void*malloc(unsigned int size);作用:作用:在内
7、存的动态存储区中分配在内存的动态存储区中分配 一个一个 长度为长度为sizesize的连续空间。的连续空间。返回值:返回值:是一个指向分配域起始地址的指针(基本是一个指向分配域起始地址的指针(基本类型类型voidvoid)。)。执行失败:执行失败:返回返回NULLNULL12函数原形:void*calloc(unsigned n,unsigned size);作用:在内存动态区中分配 n个 长度为size的连续空间。函数返回值:指向分配域起始地址的指针执行失败:返回null主要用途:为一维数组开辟动态存储空间。n 为数组元素个数,每个元素长度为size2.calloc2.calloc 函数函数
8、133.free 函数函数原形:void free(void*p);作用:释放由 p 指向的内存区。P:是最近一次调用 calloc 或 malloc 函数时返回的值。free 函数无返回值动态分配的存储单元在用完后一定要释放,否则内存会因申请空间过多引起资源不足而出现故障。14结点的动态分配ANSI C 的三个函数(头文件 malloc.h)void*malloc(unsigned int size)void*calloc(unsigned n,unsigned size)void free(void*p)C+的两个函数new 类型(初值)delete 指针变量 /*表示释放数组,可有可无)
9、*/使用 new 的优点:可以通过对象的大小直接分配,而不管对象的具体长度是多少(p340 例14.10)1511.7.4 建立动态链表基本方法:三个结点(头结点head、尾结点 NULL 和待插入结点 P)第一步:定义头结点head、尾结点 p2 和待插入结点p1,待插入的结点数据部分初始化;第二步:该结点被头结点、尾结点同时指向。P1=p2=(struct student*)malloc(LEN);头指针部分为空,head=NULL;第三步:重复申请待插入结点空间,对该结点的数据部分赋值(或输入值),将该结点插入在最前面,或者最后面(书上在尾部插入).P2-next=P1;P2=P1;最后
10、:P2-next=NULL;*head,*p1,*p2*head,*p1,*p2使用使用malloc(LEN)malloc(LEN)P2-next=NULL;1611.7.4 建立动态链表991019910189.589.5headP1p21.任务是开辟结点和输入数据任务是开辟结点和输入数据2.2.并建立前后相链的关系并建立前后相链的关系待插入的结点待插入的结点p1p1数数据部分初始化据部分初始化,该结该结点被头结点点被头结点head、尾结点尾结点p2同时指向同时指向.17图11.14991019910189.589.5headp299103991039090p1991019910189.58
11、9.5headp299103991039090p1(a)(b)p1重复申请待插入重复申请待插入结点空间,对该结结点空间,对该结点的数据部分赋值点的数据部分赋值(或输入值)(或输入值)P2-next P2-next 指向指向p1p1新开辟的结点。新开辟的结点。18图11.14head991019910189.589.5p1p299103991039090(c)P2P2指向新结指向新结点点p2=p1p2=p119图11.15991019910189.589.5991019910189.589.5p299107991078585p1head991019910189.589.5991019910189
12、.589.5p299107991078585p1head(a)(b)20 图11.169910399103909099107991078585p20 00 0p1head991019910189.589.59910399103909099107991078585NULLNULLp20 00 0p1head991019910189.589.521例11.8 建立一个有3名学生数据的单向动态链表#define NULL 0#define LEN sizeof(struct student)struct studentlong num;float score;struct student*next;
13、int n;struct student*creat(void)struct student*head;struct student*p1,*p2;n=0;p1=p2=(struct student*)malloc(LEN);scanf(%1d,%f,&p1-num,&p1-score);head=NULL;结构体类型数据的长度,结构体类型数据的长度,sizeofsizeof是是“字节数运算符字节数运算符”定义指针类型的函数。定义指针类型的函数。带回链表的起始地址带回链表的起始地址开辟长度为开辟长度为LENLEN的内存区的内存区P1,p2P1,p2是指向结构体类型数据的指针变是指向结构体类型数
14、据的指针变量,强行转换成结构体类型量,强行转换成结构体类型假设头指向空结点假设头指向空结点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-num,&p1-score);p2-next=NULL;return(head);/返回链表的头指针算法:算法:p1指向新开的结点指向新开的结点:p1=(stuct student*)malloc(LEN);p1的所指向的结点连接在的所指向的结点连接在p2所指向结
15、点后面,用所指向结点后面,用p2-next=p1来实现。来实现。p2 指向链表中最后建立的结点,指向链表中最后建立的结点,:p2=p1;头指针指向头指针指向p1结点结点P1开辟的新结点链到了开辟的新结点链到了p2的后面的后面P1继续开辟新结点继续开辟新结点给新结点赋值此给新结点赋值此2311.7.5 输出链表链表遍历1.单向链表总是从头结点开始的;2.每访问一个结点,就将当前指针向该结点的下一个结点移动:p=p-next;3.直至下一结点为空 P=NULL24图 11.18headp PPNULLNULL25void print(struct student*head)struct stude
16、nt*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!=NULL);2611.7.6 对链表的删除操作删除结点原则:不改变原来的排列顺序,只是从链表中分离开来,撤消原来的链接关系。两种情况:1、要删的结点是头指针所指的结点则直接操作;2、不是头结点,要依次往下找。另外要考虑:空表和找不到要删除的结点27链表中结点删除需要由两个临时指针:P1:判断指向的结点是不是要删除的结点(用于寻找);P2:始终指向P1的前面一个结点;
17、28图11.19ABDECABDEC(a)(B)29图11.209910199101headp199103991039910799107NULLNULL(a)(b)9910199101head99103991039910799107NULLNULLp2p1原链表原链表P1指向指向头结点头结点P2指向指向p1指向的结指向的结点。点。P1指指向下移一向下移一个结点。个结点。30图11.209910199101head99103991039910799107NULLNULLp19910199101head99103991039910799107NULLNULLp2p1(c)(d)经判断后,第经判断后
18、,第1个个结点是要删除的结点是要删除的结点,结点,head指向指向第第2个结点,第个结点,第1个结点脱离。个结点脱离。经经P1P1找到要删找到要删除的结点后使除的结点后使之脱离。之脱离。31struct 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&p1-next!=NULL)p2=p1;p1=p1-next;if(num=p1-num)if(p1=head)head=p1-n
19、ext;else p2-next=p1-next;printf(delete:%ldn,num);n=n-1;else printf(%ld not been found!n,num);end:return(head);找到了找到了没找到没找到3211.7.7 对链表的插入操作插入结点:将一个结点插入到已有的链表中插入原则:1、插入操作不应破坏原链接关系2、插入的结点应该在它该在的位置实现方法:应该有一个插入位置的查找子过程共有三种情况:1、插入的结最小2、插入的结点最大3、插入的结在中间33 操 作 分 析同删除一样,需要几个临时指针:P0:指向待插的结点;初始化:p0=数组stu;P1:指
20、向要在P1之前插入结点;初始化:p1=head;P2:指向要在P2之后插入结点;插入操作:当符合以下条件时:p0-num 与 p1-num 比较找位置if(p0-nump1-num)&(p1-next!=NULL)则插入的结点不在p1所指结点之前;指针后移,交给p2;p1=p1-next;p2=p1;则继续与 p0 指向的数组去比,直到(p1-next!=NULL)为止。否则有两种情况发生:if(head=p1)head=p0;p0-next=p1插到原来第一个结点之前;else p2-next=p0;p0-next=p1;插到 p2 指向的结点之后;还有另外一种情况:插到最后的结点之后;p1
21、-next=p0;p0-next=NULL;34图11.229910199101headp199103991039910799107NULLNULL(a)9910299102p035图11.229910199101head99103991039910799107NULLNULL9910299102p0p2p1(b)36struct 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;e
22、lse while(p0-nump1-num)&(p1-next!=NULL)p2=p1;p1=p1-next;if(p0-numnum)if(head=p1)head=p0;else p2-next=p0;p0-next=p1;else p1-next=p0;p0-next=NULL;n=n+1;return(head);原来的链表是空表原来的链表是空表P0P0指向要插的结点指向要插的结点使使p0p0指向的结点作为头结点指向的结点作为头结点使使p2指向刚才指向刚才p1指向的结点指向的结点插到原来第一个结点之前插到原来第一个结点之前插到插到p2指向的结点之后指向的结点之后插到最后的结点之后插到
23、最后的结点之后链接375 5head6 610101515null12128 8课堂举例:课堂举例:已有一个如图所示的链表;已有一个如图所示的链表;它是按结点中的整数域从小到大排序的,现在要插它是按结点中的整数域从小到大排序的,现在要插入一个结点,该结点中的数为入一个结点,该结点中的数为1010待插入结点待插入结点此结点已插入链表此结点已插入链表38分析:分析:按三种情况按三种情况1 1、第一种情况,链表还未建成(空链表),待插入结点、第一种情况,链表还未建成(空链表),待插入结点p p实际上是第一个结点。这时必然有实际上是第一个结点。这时必然有head=nullhead=null。只要。只要
24、让头指针指向让头指针指向 p p 就可以了。语句为就可以了。语句为6nullheadphead=p;p-next=null;2 2、第二种情况,链表已建成,待插入结点、第二种情况,链表已建成,待插入结点 p p 的数据要的数据要比头结点的数据还要小,这时有比头结点的数据还要小,这时有(p-num)num)p-num)num)当然当然p p结点要插在结点要插在headhead结点前。结点前。396head8512nullheadpp-next=head;head=p;语句为语句为null403 3、第三种情况,链表已建成,待插入结点、第三种情况,链表已建成,待插入结点 p p 的数据比头结点的数
25、据大,需要找到正确的的数据比头结点的数据大,需要找到正确的插入位置。这时,可以借助两个结构指针插入位置。这时,可以借助两个结构指针r r 和和 g g,利用循环比较来找到正确位置。然后,利用循环比较来找到正确位置。然后将结点将结点 p p 插入到链表中正确的位置。插入到链表中正确的位置。参见下面的图示参见下面的图示416head81213nullp15gr说明:说明:这种情况下,这种情况下,p p 结点已经与链表的第一个结点结点已经与链表的第一个结点比较过了,所以从链表的下一个结点开始比较。比较过了,所以从链表的下一个结点开始比较。138138,继续比较。,继续比较。426head81213n
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 指针 结构 详解
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【胜****】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【胜****】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。