《清华大学C语言教学课件(共16个PPT)第12个教学提纲.ppt》由会员分享,可在线阅读,更多相关《清华大学C语言教学课件(共16个PPT)第12个教学提纲.ppt(45页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、清华大学C语言教学课件(共16个PPT)第12个5 5head6 610101515nullnull12128 8先看下面一个简单的例子:先看下面一个简单的例子:已有一个如图所示的链表。已有一个如图所示的链表。它是按结点中的整数域从小到大排序的。现在要插它是按结点中的整数域从小到大排序的。现在要插入一个结点,该节点中的数为入一个结点,该节点中的数为10。待插入结点待插入结点此结点已插入链表此结点已插入链表2/结构结构7.c#include/预编译命令预编译命令#include/内存空间分配内存空间分配#define null 0/定义空指针常量定义空指针常量#define LEN sizeof
2、(struct numST)/定义常量,表示结构长度定义常量,表示结构长度struct numST/结构声明结构声明int num;/整型数整型数struct numST*next;/numST结构指针结构指针;参考程序参考程序3/被调用函数被调用函数insert(),两个形参分别表示链表和待插入的结点,两个形参分别表示链表和待插入的结点void insert(struct numST*phead,struct numST*p)/函数体开始函数体开始struct numST*q,*r;/定义结构指针定义结构指针q,rif(*phead)=null)/第一种情况第一种情况,链表为空,链表为空*p
3、head=p;/链表头指向链表头指向preturn;/完成插入操作,返回完成插入操作,返回else/链表不为空链表不为空/第二种第二种情况情况,p结点结点num值小于链表头结点的值小于链表头结点的num值值if(*phead)-num p-num)/将将p结点插到链表头部结点插到链表头部 p-next=*phead;/将将p的的next指针指向链表头指针指向链表头(*phead)*phead=p;/将链表头赋值为将链表头赋值为p return;/返回返回4/第三种第三种情况情况,循环查找正确位置,循环查找正确位置r=*phead;/r赋值为链表头赋值为链表头q=(*phead)-next;/q
4、赋值为链表的下一个结点赋值为链表的下一个结点while(q!=null)/利用循环查找正确位置利用循环查找正确位置/判断当前结点判断当前结点num是否小于是否小于p结点的结点的numif(q-num num)r=q;/r赋值为赋值为q,即指向,即指向q所指的结点所指的结点q=q-next;/q指向链表中相邻的下一个结点指向链表中相邻的下一个结点else/找到了正确的位置找到了正确的位置break;/退出循环退出循环/将将p结点插入正确的位置结点插入正确的位置r-next=p;p-next=q;5/被调用函数,形参为被调用函数,形参为ST结构指针结构指针,用于输出链表内容用于输出链表内容void
5、 print(struct numST*head)int k=0;/整型变量,用于计数整型变量,用于计数struct numST*r;/声明声明r为为ST结构指针结构指针r=head;/r赋值为赋值为head,即指向,即指向链表头链表头 while(r!=null)/当型循环,链表指针不为空当型循环,链表指针不为空则则继续继续/循环体开始循环体开始k=k+1;/计数加计数加1printf(%d%dn,k,r-num);r=r-next;/取链表中相邻的下一个结点取链表中相邻的下一个结点/循环体结束循环体结束6void main()/主函数开始主函数开始/函数体开始函数体开始struct num
6、ST*head,*p;/ST型结构指针型结构指针head=null;/初始化初始化head为为null/分配分配3个个ST结构的内存空间,用于构造链表结构的内存空间,用于构造链表head=(struct numST*)malloc(LEN);head-next=(struct numST*)malloc(LEN);head-next-next=(struct numST*)malloc(LEN);/为链表中的为链表中的3个结点中的个结点中的num赋值为赋值为5、10和和15head-num=5;head-next-num=10;head-next-next-num=15;head-next-n
7、ext-next=null;/链表尾赋值为空链表尾赋值为空/构造一个结点构造一个结点p,用于插入链表,用于插入链表p=(struct numST*)malloc(LEN);p-num=12;p-next=null;insert(&head,p);/调用调用insert函数将结点函数将结点p插入链表插入链表print(head);/调用调用print函数,输出链表内容函数,输出链表内容/主函数结束主函数结束71、定义两个、定义两个ST型结构指针型结构指针*head,*p,并让,并让head=null;2、分配、分配3个个ST结构的内存空间,用于构造链表结构的内存空间,用于构造链表(1)head=
8、(struct numST*)malloc(LEN);(2)head-next=(struct numST*)malloc(LEN);(3)head-next-next=(struct numST*)malloc(LEN);先看主函数先看主函数head这这3个个ST结构的内存空间如上图所示。结构的内存空间如上图所示。head-nexthead-next-next8下面用赋值语句往这下面用赋值语句往这3个空间中放个空间中放num数据。最后的数据。最后的一个结点为队尾,在其指针域存放一个结点为队尾,在其指针域存放null。(4)head-num=5;(5)head-next-num=10;(6)h
9、ead-next-next-num=15;(7)head-next-next-next=null;做了这做了这4条之后形成了一条链表如下:条之后形成了一条链表如下:5 5head10101515nullnull该链表的头结点由该链表的头结点由head所指向。所指向。93、构造一个结点、构造一个结点p,在,在p结点的数据域放结点的数据域放12,再插入,再插入链表链表(1)p=(struct numST*)malloc(LEN);(2)p-num=12;(3)p-next=null;4、调用、调用insert函数来插入函数来插入p结点。结点。语句为语句为 insert(&head,p);意思是以将
10、意思是以将p插入到以插入到以head为队头的链表中。但这为队头的链表中。但这里在调用时,不是用里在调用时,不是用head作为实参,而是用作为实参,而是用&head作为实参,属于作为实参,属于传址调用传址调用,而非,而非传值调用传值调用。10这里要讲传址调用和传值调用的区别这里要讲传址调用和传值调用的区别(1)如果是传值调用)如果是传值调用主程序中的调用语句为主程序中的调用语句为 insert(head,p);被调用函数为被调用函数为void insert(struct munST*phead,struct numST*p);headp实际参数实际参数形式参数形式参数pphead11当着实际参数
11、当着实际参数head赋给了形式参数赋给了形式参数phead之后,之后,phead就指向了已经存在了的链表,见下图。就指向了已经存在了的链表,见下图。5 510101515nullnullphead这时原来的主程序中的头指针就不再起作用了。而是这时原来的主程序中的头指针就不再起作用了。而是phead起作用。假如现在起作用。假如现在p中的结点数据为中的结点数据为4小于小于5,应该将应该将p插入到插入到phead所指向的结点前,如下图所指向的结点前,如下图head125 5head10101515nullnullphead被调用函数无法改变被调用函数无法改变head,这时,这时head不再是头结点的
12、不再是头结点的指针了。如果被调用函数返回指针了。如果被调用函数返回head,主函数只能表,主函数只能表示示head为头指针的三个结点,新插入的结点并没有为头指针的三个结点,新插入的结点并没有包含进去。要想将新的插入到最前面的结点包含进去,包含进去。要想将新的插入到最前面的结点包含进去,就必须用传址调用。就必须用传址调用。4 4phead13(2)如果是传址调用)如果是传址调用主程序中的调用语句为主程序中的调用语句为 insert(&head,p);被调用函数为被调用函数为void insert(struct munST*phead,struct numST*p);先看先看 struct num
13、ST*phead 是说定义(是说定义(*phead)为指向)为指向numST结构的指针。结构的指针。*phead是指向是指向numST结构的指针结构的指针,phead又是指向又是指向*phead这个指针的指针。这个指针的指针。phead=&head14 主程序中的实参为链表头指针主程序中的实参为链表头指针head所在的地址值,所在的地址值,传给被调用函数的传给被调用函数的phead的指针变量中,起到了让的指针变量中,起到了让phead也指向也指向head的目的。的目的。&headpheadhead15在主函数中在主函数中head为头指针,在被调用的子函数中为头指针,在被调用的子函数中phead
14、为头指针的地址,为头指针的地址,head和和*phead是同一个单元,是同一个单元,只不过分别叫不同的名罢了。当然在子函数中无论插只不过分别叫不同的名罢了。当然在子函数中无论插入什么结点都会让入什么结点都会让*phead指向链表的头。自然返回到指向链表的头。自然返回到主函数后,主函数后,head也会是指向同一链表的头。也会是指向同一链表的头。从这个例子中读者可以领回到传值调用与传址调从这个例子中读者可以领回到传值调用与传址调用的区别。用的区别。5、这样在子函数做插入结点的过程中,头指针的改变、这样在子函数做插入结点的过程中,头指针的改变也能反映到主函数中来。调用也能反映到主函数中来。调用pri
15、nt函数,从函数,从head开开始输出整个链表的内容。始输出整个链表的内容。16下面我们来研究下面我们来研究insert函数函数前提是主程序已将两个实参传给了前提是主程序已将两个实参传给了insert函数的两个形参,函数的两个形参,这时这时*phead=head,p所指向的就是待插入的一个结点。所指向的就是待插入的一个结点。事先定义两个结构指针事先定义两个结构指针q和和r。第一种情况:第一种情况:*phead=null,说明主程序传过来的头指针为空,即,说明主程序传过来的头指针为空,即链表为空,一个结点都不存在。这时待插入的链表为空,一个结点都不存在。这时待插入的p结点就结点就是链表中的第一个
16、结点。只要执行如下两条语句即可是链表中的第一个结点。只要执行如下两条语句即可*phead=p;/将表头指针指向将表头指针指向p结点结点 return;/返回主程序返回主程序在主程序中必然头指针在主程序中必然头指针head指向指向p结点。结点。17第二种情况:第二种情况:p结点的结点的num值小于链表头结点的值小于链表头结点的num值,即值,即(*phead)-nump-num。这时要将。这时要将p结点插入到头结结点插入到头结点的前面,要执行如下三条语句点的前面,要执行如下三条语句p-next=*phead;/在在p结点的指针域赋以头结点的地址值结点的指针域赋以头结点的地址值*phead=p;/
17、将头结点指针将头结点指针phead指向指向p结点结点return;/返回主程序返回主程序这种情况如下图这种情况如下图5 5*phead10104 41515nullnull*pheadpnull18第三种情况:第三种情况:前两种情况,无论遇到哪一种,都会返回主程序。只要不返回就前两种情况,无论遇到哪一种,都会返回主程序。只要不返回就是这第三种情况,即是这第三种情况,即p结点的结点的num大于头指针所指向的结点的大于头指针所指向的结点的num值。这时肯定地说值。这时肯定地说p结点要插入到头结点之后,究竟要插到结点要插入到头结点之后,究竟要插到哪里需要找到应该插入的位置。我们设指针哪里需要找到应该
18、插入的位置。我们设指针r和指针和指针q,分别指向,分别指向相邻的两个结点,相邻的两个结点,r在前在前q在后,当着满足在后,当着满足r-num num num时,时,p就插在就插在r与与q之间。我们看图之间。我们看图5 5head10101212p1515nullnullqrnullqr19一开始让一开始让 r=*phead,让,让 q=*phead-next(1)当指针当指针q为空指针时,说明原链表中只有一个结点,为空指针时,说明原链表中只有一个结点,即即r指向的结点,这时只要将指向的结点,这时只要将p结点接在结点接在r之后即可。之后即可。执行执行r-next=p;p-next=q;(2)如果
19、如果q!=null,说明起码有两个结点在链表中,接着,说明起码有两个结点在链表中,接着要判要判p结点的结点的num值是否大于值是否大于q结点的结点的num值。如果值。如果是大,则说明是大,则说明p应插在应插在q之后而不是之前,这时让之后而不是之前,这时让r和和q指针同时后移一步,即指针同时后移一步,即r=q;q=q-next;20执行执行(2)在在q!=null的情况下,如果的情况下,如果p-numnum了,说明这了,说明这时找到了正确的插入位置,退出时找到了正确的插入位置,退出while循环,将循环,将p结点结点插入到插入到r后,后,q前即可。使用的语句为前即可。使用的语句为在下面我们画出该
20、算法的结构框图在下面我们画出该算法的结构框图r-next=p;p-next=q;2122作业作业1、按下表顺序输入某班的一个学习小组的成员表、按下表顺序输入某班的一个学习小组的成员表希望你将学习小组形成一个链表,每人一个结点。结点希望你将学习小组形成一个链表,每人一个结点。结点中有四个成员:姓名、出生年、出生月、指针。在链中有四个成员:姓名、出生年、出生月、指针。在链表中生日大者在前,小者在后。表中生日大者在前,小者在后。建成链表后输出该链表。建成链表后输出该链表。姓名姓名姓名姓名赵达赵达赵达赵达钱亮钱亮钱亮钱亮孙参孙参孙参孙参李思李思李思李思周芜周芜周芜周芜武陆武陆武陆武陆郑琪郑琪郑琪郑琪出
21、出出出 年年年年生生生生 月月月月198319831983198319831983198219821983198319831983198219821 13 32 29 95 54 46 6232、一年后钱亮同学调至其它学习小组,希望你编程从、一年后钱亮同学调至其它学习小组,希望你编程从原链表中删除钱亮所在结点,之后输出该链表。原链表中删除钱亮所在结点,之后输出该链表。提示:原链表如下:提示:原链表如下:李思李思李思李思198219829 9head武陆武陆武陆武陆198319834 4赵达赵达赵达赵达198319831 1孙参孙参孙参孙参198319832 2钱亮钱亮钱亮钱亮198319833
22、 3郑琪郑琪郑琪郑琪198219826 6周芜周芜周芜周芜198319835 5nullnull查找待删除的结点的位置,要从链头找起。查找待删除的结点的位置,要从链头找起。(1)如果是链头结点,即有如果是链头结点,即有head-name=待删者待删者name这时只要做这时只要做head=head-next;即可即可(2)如果不是链头结点,要设两个指针如果不是链头结点,要设两个指针r和和q,初始时让,初始时让r=head;q=head-next;24(3)只要只要q!=null,就比较,就比较q-name是否为待删者的是否为待删者的name?如果是则让?如果是则让 r-next=q-next;如
23、不是,就如不是,就让让r与与q同时后移一步,即同时后移一步,即 r=q;q=q-next;然后转然后转向向(3)(4)如果发现如果发现q已是已是null,又未找到待删结点,则输出,又未找到待删结点,则输出该人不在这个表中的信息。该人不在这个表中的信息。在原链表中一旦查到钱亮所在结点位置在原链表中一旦查到钱亮所在结点位置q,让,让r-next=q-next;意味着将孙参所在结点指向钱亮的指针,不再指向意味着将孙参所在结点指向钱亮的指针,不再指向钱亮,而指向武陆钱亮,而指向武陆25二二 叉叉 树树26链表结构是利用结构中的指针域将每个结点链接起来,链表结构是利用结构中的指针域将每个结点链接起来,形
24、似链条,属于线性结构数据。形似链条,属于线性结构数据。下面介绍一种非线性结构的东西,下面介绍一种非线性结构的东西,二叉树二叉树。先看下例:先看下例:6 6L L R R9 9nullnull nullnull5 5nullnullnullnull7 7nullnull nullnull3 3n nulull ln nu ull ll8 8L L R R4 4L L R R结点结点1结点结点2结点结点4结点结点6结点结点7结点结点5结点结点3root27在图中在图中(1)外形象一棵倒立的树)外形象一棵倒立的树(2)最上层有一个)最上层有一个“根结点根结点”,指针,指针root指向根结点。指向根结
25、点。(3)每个结点都是一个结构,一个成员是整型数据,两)每个结点都是一个结构,一个成员是整型数据,两个成员是指针,分为左指针个成员是指针,分为左指针L和右指针和右指针R。(4)根结点的左指针指向左子树;右指针指向右子树。)根结点的左指针指向左子树;右指针指向右子树。(5)左子树或右子树本身又是一棵二叉树,又有它们自)左子树或右子树本身又是一棵二叉树,又有它们自己的左子树和右子树,己的左子树和右子树,这是递归定义的,因此,在处理时常可用递归算法。这是递归定义的,因此,在处理时常可用递归算法。28二叉树的遍历二叉树的遍历树的遍历是指访遍树中的所有结点。树的遍历是指访遍树中的所有结点。对比看遍历一个
26、单链表,从表头开始按一个方对比看遍历一个单链表,从表头开始按一个方向从头到尾就可遍历所有结点。对二叉树来向从头到尾就可遍历所有结点。对二叉树来说就没有这样简单了,因为对树或是对子树说就没有这样简单了,因为对树或是对子树都存在根(或子树的根)和左子树、右子树,都存在根(或子树的根)和左子树、右子树,先遍历谁?由之产生了三种不同的方法:先遍历谁?由之产生了三种不同的方法:291、前序法:、前序法:1.1 先访问根结点;先访问根结点;1.2 遍历左子树;遍历左子树;1.3 遍历右子树;遍历右子树;2、中序法:、中序法:2.1 遍历左子树;遍历左子树;2.2 访问根;访问根;2.3 遍历右子树;遍历右
27、子树;3、后序法、后序法3.1 遍历左子树;遍历左子树;3.2 遍历右子树;遍历右子树;3.3 访问根;访问根;30我们就以中序法为例研究如何遍历二叉树。仍然采用我们就以中序法为例研究如何遍历二叉树。仍然采用递归算法。令指针递归算法。令指针p指向二叉树的根结点指向二叉树的根结点定义树的结构定义树的结构struct TREEint data;struct TREE*L,*R;定义定义p为为TREE结构的指针结构的指针struct TREE*p;让让LNR(P)为对以为对以p为根的树作中序遍历的子函数。可为根的树作中序遍历的子函数。可得出如下图所示的递归算法与或结点图得出如下图所示的递归算法与或结
28、点图3132该图说明如下:该图说明如下:1、A结点表示中序遍历结点表示中序遍历p结点为根的二叉树,函数为结点为根的二叉树,函数为LNR(p)。该结点为。该结点为“或或”结点,有两个分支。当结点,有两个分支。当p为空时,为空时,A取取B结点,什么都不做;当结点,什么都不做;当p不空时,说不空时,说明树存在(起码有一个根),有结点明树存在(起码有一个根),有结点C。2、C结点为一个结点为一个“与与”结点,要依次做相关联的三件结点,要依次做相关联的三件事情:事情:2.1 D结点:中序遍历结点:中序遍历p的左子树,函数为的左子树,函数为LNR(p-L);2.2 E结点:直接可解结点,访问结点:直接可解
29、结点,访问p结点(比如输出结点(比如输出p结点数据域中的值)。结点数据域中的值)。2.3 F结点:中序遍历结点:中序遍历p的右子树,函数为的右子树,函数为LNR(p-R)333、比较、比较LNR(p)与与LNR(p-L)及及LNR(p-R)可以看出,可以看出,都是同一个函数形式,只不过代入了不同的参数,都是同一个函数形式,只不过代入了不同的参数,从层次和隶属关系看,从层次和隶属关系看,p是父结点的指针,而是父结点的指针,而p-L和和p-R是子结点的指针,是子结点的指针,p-L是左子树的根,是左子树的根,p-R是是右子树的根。右子树的根。下面请大家做一个练习,依图下面请大家做一个练习,依图2画画
30、“与或与或”图将图图将图1所所示的二叉树用中序遍历,将所访问到的结点数据输示的二叉树用中序遍历,将所访问到的结点数据输出。如图出。如图334什么都不做什么都不做访问结点访问结点1:输出输出335二叉树的建立二叉树的建立建立二叉树的过程是一个建立二叉树的过程是一个“插入插入”过程,下面我们用过程,下面我们用一个例子来讲解这一过程。一个例子来讲解这一过程。我们想建立这样一棵二叉树,树中的每一个结点有一我们想建立这样一棵二叉树,树中的每一个结点有一个整数数据名为个整数数据名为data,有两个指针:左指针,有两个指针:左指针L,右指,右指针针R,分别指向这个结点的左子树和右子树,显然可,分别指向这个结
31、点的左子树和右子树,显然可以用如下名为以用如下名为TREE的结构来描述这种结点:的结构来描述这种结点:struct TREEint data;struct TREE*L,*R;36对二叉树最重要的是根,它起定位的作用,因此,首先对二叉树最重要的是根,它起定位的作用,因此,首先建立的是根结点。也就是说,如果从键盘输入数据来建立的是根结点。也就是说,如果从键盘输入数据来建立二叉树,第一个数据就是这棵树的根的数据,之建立二叉树,第一个数据就是这棵树的根的数据,之后再输入的数据,每一个都要与根中的数据作比较,后再输入的数据,每一个都要与根中的数据作比较,以便确定该数据所在接点的插入位置。假定我们这里以
32、便确定该数据所在接点的插入位置。假定我们这里依然用图依然用图1的中序遍历的方式。即如果待插入结点的的中序遍历的方式。即如果待插入结点的数据比根结点的数据小,则将其插至左子树,否则插数据比根结点的数据小,则将其插至左子树,否则插入右子树。入右子树。定义一个递归函数定义一个递归函数void insert(struct TREE*proot,struct TREE*p)其中,指针其中,指针p指向含有待插入数据的结点。指向含有待插入数据的结点。proot为树的根指针的地址。为树的根指针的地址。insert函数棵理解为将函数棵理解为将p结点插入到结点插入到*proot所指向所指向的树中。的树中。37in
33、sert(proot,p)可用下列与或结点图来描述可用下列与或结点图来描述38注意在上图中注意在上图中proot是被调用函数的形参。从前面对它是被调用函数的形参。从前面对它的定义看,的定义看,proot是指针的指针,实际上是指向二叉树是指针的指针,实际上是指向二叉树根结点的指针的指针,或者说是指向二叉树根结点的根结点的指针的指针,或者说是指向二叉树根结点的指针的地址。如下图。因此,在主程序调用指针的地址。如下图。因此,在主程序调用insert函函数时,数时,根结点根结点proot实参实参&root实参为实参为&root,p形参为形参为 proot,p下面是建立二叉树的参考程序。下面是建立二叉树
34、的参考程序。39#include/预编译命令预编译命令#include/内存空间分配内存空间分配#define null 0/定义空指针常量定义空指针常量#define LEN sizeof(struct TREE)/定义常量,表示结构长度定义常量,表示结构长度struct TREE/结构声明结构声明int data;/整型数整型数struct TREE*L,*R;/TREE结构指针结构指针;40/被调用函数被调用函数insert,将结点插入二叉树,将结点插入二叉树void insert(struct TREE*proot,struct TREE*p)/函数体开始函数体开始if(*proot=
35、null)/如果根结点为空如果根结点为空*proot=p;/将结点将结点p插入根结点插入根结点return;/返回返回else/根结点不为空根结点不为空/如果如果p结点数据小于等于根结点数据结点数据小于等于根结点数据if(p-data data)insert(&(*proot)-L),p);/插入左子树插入左子树else/如果如果p结点数据大于等于根结点数据结点数据大于等于根结点数据insert(&(*proot)-R),p);/插入右子树插入右子树/函数体结束函数体结束41/被调用函数,形参为被调用函数,形参为TREE结构指针,输出二叉树内容结构指针,输出二叉树内容void print(st
36、ruct TREE*root)/函数体开始函数体开始if(root=null)/根或子树根结点为空根或子树根结点为空return;/返回返回print(root-L);/输出左子树内容输出左子树内容printf(%d,root-data);/输出根结点内容输出根结点内容print(root-R);/输出右子树内容输出右子树内容/被调用函数结束被调用函数结束void main()/主函数开始主函数开始/函数体开始函数体开始struct TREE*root,*p;/TREE型结构指针型结构指针int temp;/临时变量,用于用户输入数据临时变量,用于用户输入数据root=null;/初始化二叉树
37、根结点为空初始化二叉树根结点为空p=null;/初始化待插入结点的指针为空初始化待插入结点的指针为空printf(请输入待插入结点的数据请输入待插入结点的数据n);/提示信息提示信息printf(如果输入如果输入-1表示插入过程结束表示插入过程结束n);/提示信息提示信息scanf(%d,&temp);/输入待插入结点数据输入待插入结点数据42while(temp!=-1)/当型循环,当型循环,-1为结束标志为结束标志/循环体开始循环体开始/为待插入结点分配内存单元为待插入结点分配内存单元p=(struct TREE*)malloc(LEN);p-data=temp;/将将temp赋值给赋值给
38、p结点的数据域结点的数据域p-L=p-R=null;/将将p结点的左右指针域置为空结点的左右指针域置为空insert(&root,p);/将将p结点插入到根为结点插入到根为root的树中,的树中,/&root表示二叉树根结点的地址表示二叉树根结点的地址printf(请输入待插入结点的数据请输入待插入结点的数据n);/提示信息提示信息printf(如果输入如果输入-1表示插入过程结束表示插入过程结束n);/提示信息提示信息scanf(%d,&temp);/输入待插入结点数据输入待插入结点数据/循环体结束循环体结束if(root=null)/如果根结点为空如果根结点为空printf(这是一棵空树。这是一棵空树。n);/输出空树信息输出空树信息else/根结点不为空根结点不为空print(root);/调用调用print函数,输出二叉树内容函数,输出二叉树内容/主函数结束主函数结束43结结 束束44此课件下载可自行编辑修改,仅供参考!此课件下载可自行编辑修改,仅供参考!感谢您的支持,我们努力做得更好!谢谢感谢您的支持,我们努力做得更好!谢谢