ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:224.80KB ,
资源ID:5310583      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5310583.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(二叉树遍历C语言递归非递归六种算法说课讲解.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

二叉树遍历C语言递归非递归六种算法说课讲解.docx

1、二叉树遍历C语言递归非递归六种算法说课讲解二叉树遍历C语言(递归,非递归)六种算法数据结构(双语)项目文档报告用两种方式实现表达式自动计算专 业: 班 级: 指导教师: 姓 名: 学 号: 一、设计思想.01二、算法流程图.02三、源代码.04四、运行结果.11五、遇到的问题及解决.11六、心得体会.12一、设计思想二叉树的遍历分为三种方式,分别是先序遍历,中序遍历和后序遍历。先序遍历实现的顺序是:根左右,中序遍历实现的是:左根右,后续遍历实现的是:左右根。根据不同的算法分,又分为递归遍历和非递归遍历。递归算法:1先序遍历:先序遍历就是首先判断根结点是否为空,为空则停止遍历,不为空则将左子作为

2、新的根结点重新进行上述判断,左子遍历结束后,再将右子作为根结点判断,直至结束。到达每一个结点时,打印该结点数据,即得先序遍历结果。2.中序遍历:中序遍历是首先判断该结点是否为空,为空则结束,不为空则将左子作为根结点再进行判断,打印左子,然后打印二叉树的根结点,最后再将右子作为参数进行判断,打印右子,直至结束。3.后续遍历:指针到达一个结点时,判断该结点是否为空,为空则停止遍历,不为空则将左子作为新的结点参数进行判断,打印左子。左子判断完成后,将右子作为结点参数传入判断,打印右子。左右子判断完成后打印根结点。非递归算法:1.先序遍历:首先建立一个栈,当指针到达根结点时,打印根结点,判断根结点是否

3、有左子和右子。有左子和右子的话就打印左子同时将右子入栈,将左子作为新的根结点进行判断,方法同上。若当前结点没有左子,则直接将右子打印,同时将右子作为新的根结点判断。若当前结点没有右子,则打印左子,同时将左子作为新的根结点判断。若当前结点既没有左子也没有右子,则当前结点为叶子结点,此时将从栈中出栈一个元素,作为当前的根结点,打印结点元素,同时将当前结点同样按上述方法判断,依次进行。直至当前结点的左右子都为空,且栈为空时,遍历结束。2.中序遍历:首先建立一个栈,定义一个常量flag(flag为0或者1),用flag记录结点的左子是否去过,没有去过为0,去过为1,默认为0.首先将指针指向根结点,将根

4、结点入栈,然后将指针指向左子,左子作为新的结点,将新结点入栈,然后再将指针指向当前结点的左子,直至左子为空,则指针返回,flag置1,出栈一个元素,作为当前结点,打印该结点,然后判断flag,flag为1则将指针指向当前结点右子,将右子作为新的结点,结点入栈,再次进行上面的判断,直至当前结点右子也为空,则再出栈一个元素作为当前结点,一直到结束,使得当前结点右子为空,且栈空,遍历结束。3.后续遍历:首先建立两个栈,然后定义两个常量。第一个为status,取值为0,1,2.0代表左右子都没有去过,1代表去过左子,2,代表左右子都去过,默认为0。第二个常量为flag,取值为0或者1,0代表进左栈,1

5、代表进右栈。初始时指针指向根结点,判断根结点是否有左子,有左子则,将根结点入左栈,status置0,flag置0,若没有左子则判断结点有没有右子,有右子就把结点入右栈,status置0,flag置1,若左右子都没有,则打印该结点,并将指针指向空,此时判断flag,若flag为0,则从左栈出栈一个元素作为当前结点,重新判断;若flag为1则从右栈出栈一个元素作为当前结点,重新判断左右子是否去过,若status为1,则判断该结点有没有右子,若有右子,则将该结点入右栈,status置1,flag置1,若没有右子,则打印当前结点,并将指针置空,然后再次判断flag。若当前结点status为2,且栈为空

6、,则遍历结束。若指针指向了左子,则将左子作为当前结点,判断其左右子情况,按上述方法处理,直至遍历结束。二、算法流程图图1 二叉树的建立用先序方法建立二叉树,为每个结点定义左右子,用0代表空,得到上述二叉树图2 非递归二叉树遍历 先序首先建立一个栈,当指针到达根结点时,打印根结点,判断根结点是否有左子和右子。有左子和右子的话就打印左子同时将右子入栈,将左子作为新的根结点进行判断,方法同上。若当前结点没有左子,则直接将右子打印,同时将右子作为新的根结点判断。若当前结点没有右子,则打印左子,同时将左子作为新的根结点判断。若当前结点既没有左子也没有右子,则当前结点为叶子结点,此时将从栈中出栈一个元素,

7、作为当前的根结点,打印结点元素,同时将当前结点同样按上述方法判断,依次进行。直至当前结点的左右子都为空,且栈为空时,遍历结束。图3 非递归二叉树遍历 中序中序遍历:首先建立一个栈,定义一个常量flag(flag为0或者1),用flag记录结点的左子是否去过,没有去过为0,去过为1,默认为0.首先将指针指向根结点,将根结点入栈,然后将指针指向左子,左子作为新的结点,将新结点入栈,然后再将指针指向当前结点的左子,直至左子为空,则指针返回,flag置1,出栈一个元素,作为当前结点,打印该结点,然后判断flag,flag为1则将指针指向当前结点右子,将右子作为新的结点,结点入栈,再次进行上面的判断,直

8、至当前结点右子也为空,则再出栈一个元素作为当前结点,一直到结束,使得当前结点右子为空,且栈空,遍历结束。图4 非递归二叉树遍历 后序首先建立两个栈,然后定义两个常量。第一个为status,取值为0,1,2.0代表左右子都没有去过,1代表去过左子,2,代表左右子都去过,默认为0。第二个常量为flag,取值为0或者1,0代表进左栈,1代表进右栈。初始时指针指向根结点,判断根结点是否有左子,有左子则,将根结点入左栈,status置0,flag置0,若没有左子则判断结点有没有右子,有右子就把结点入右栈,status置0,flag置1,若左右子都没有,则打印该结点,并将指针指向空,此时判断flag,若f

9、lag为0,则从左栈出栈一个元素作为当前结点,重新判断;若flag为1则从右栈出栈一个元素作为当前结点,重新判断左右子是否去过,若status为1,则判断该结点有没有右子,若有右子,则将该结点入右栈,status置1,flag置1,若没有右子,则打印当前结点,并将指针置空,然后再次判断flag。若当前结点status为2,且栈为空,则遍历结束。若指针指向了左子,则将左子作为当前结点,判断其左右子情况,按上述方法处理,直至遍历结束。三、源代码 下面给出的是用递归算法实现的程序的源代码:#include#include/用递归的方式遍历二叉树typedef struct node /定义二叉树的结

10、点 int data; /结点的数据 struct node*lChild,*rChild; /结点左右子Node;int i=-1; /控制下面函数中循环的Node *buildTree(int *b) /产生二叉树(利用先序递归产生) Node *p; /创建一个根结点指针 if(b+i=0)p=NULL; /如果传入的当前值为0 则设其为空结点 else p=(Node*)malloc(sizeof(Node); /开辟内存 p-data=bi; /设置当前结点的数据 p-lChild=buildTree(b); /左子结点 p-rChild=buildTree(b); /右子 retu

11、rn p; /把创建的树的根节点返回void preOrder(Node *root) /前序遍历 if(root!=0) /如果根节点不为0 printf(%d ,root-data); /打印当前结点 preOrder(root-lChild); /指向左子 preOrder(root-rChild); /指向右子 void inOrder(Node *root) /中序遍历 if(root!=0) /如果根节点不为0 inOrder(root-lChild); /指向左子 printf(%d ,root-data); /打印当前结点 inOrder(root-rChild); /指向右子

12、 void postOrder(Node *root) if(root!=0) postOrder(root-lChild); /指向左子 postOrder(root-rChild); /指向右子 printf(%d ,root-data); /打印当前结点 void main()/按先序次序输入树的结点(非0整数)来创建一个树 空结点用0表示 int a = 1,2,4,0,7,0,0,0,3,5,0,0,6,8,0,0,9,0,0; int *b = a; /将指向数组首地址的指针传给 bulidTree 函数 来创建树 Node *root = buildTree(b); printf

13、(用递归方法 nn前序遍历: ); /打印提示内容 preOrder(root); /调用前序遍历函数 printf(n中序遍历: ); /打印提示内容 inOrder(root); /调用中序遍历函数 printf(n后序遍历: ); /打印提示内容 postOrder(root); /调用后序遍历函数 getch();下面给出的是用非递归算法实现的程序的源代码:#include#include/用非递归的方式遍历二叉树typedef struct node /定义二叉树的结点 int data; /结点的数据 struct node *lChild,*rChild; /结点左右子Node;

14、typedef struct /创建栈 Node *bottom; /栈底指针 Node *top; /栈顶指针Stack;void init(Stack *s) /初始化栈 s-bottom=(Node *)malloc(100*sizeof(Node); /为指针开辟内存 s-top=s-bottom; /栈顶指针指向栈底指针int isEmpty(Stack s) /判断栈是否为空的函数 if(s.top=s.bottom) return 1; /栈空 返回1 else return 0; /不为空返回 0void push(Stack *s,Node node) /栈的push方法 *

15、(s-top+)=node; /给栈顶赋值 然后top+1Node pop(Stack *s) /出栈函数 Node node; /声明一Node类型遍量 node=*(-(s-top); /node 为栈顶元素 然后top-1 return node; /返回pop出的结点Node peek(Stack *s) /看栈顶元素 return *(s-top-1); /返回栈顶元素 typedef struct /创建栈(MyStack)结构体 Node *bottom; /栈底指针 Node *top; /栈顶指针MyStack;void init1(MyStack *s) /初始化栈 s-b

16、ottom=(Node *)malloc(100*sizeof(Node); /开辟内存 s-top=s-bottom; /栈顶指针指向栈底指针void push1(MyStack *s,Node node) /进栈方法 *(s-top+)=node; /给栈顶赋值 然后top+1Node pop1(MyStack *s) /出栈函数 Node node; /声明一Node类型遍量 node=*(-(s-top); /node 为栈顶元素然后top-1 return node; /返回pop出的结点Node peek1(MyStack *s) /查栈顶元素 return *(s-top-1);

17、 /返回栈顶元素 int isEmpty1(MyStack s) /判断栈是否为空 if(s.top=s.bottom) return 1; /栈空了 返回1 else return 0; /不为空返回 0int temp=-1; Node *buildTree(int *b) /产生二叉树 Node *p; /创建一个根结点指针 if(b+temp=0) p=NULL; /如果传入的当前值为0 则设其为空结点 else p=(Node*)malloc(sizeof(Node); /开辟内存 p-data=btemp; /设置当前结点的数据 p-lChild=buildTree(b); /左子

18、结点 p-rChild=buildTree(b); /右子 ; return p; /把创建的树的根结点返回void preOrder(Node *root) /前序遍历 Stack po; /声明一个栈 Node curr = *root; /当前结点为根结点 init(&po); /初始化找 while(curr.data!=0|!isEmpty(po) /当前结点不为空 且 栈不为空 if(curr.data=0) /如果当前结点为空 curr=pop(&po); /当前结点指向 pop出栈的结点 if(curr.rChild!=NULL) /如果右子为空 push(&po,*curr.

19、rChild); /将右子进栈 printf(%d ,curr.data); /打印当前结点的内容 if(curr.lChild!=NULL) /如果左子不为空 curr=*curr.lChild; /当前子指向左子 else curr=pop(&po); /当前子指向pop出栈结点 if(curr.lChild=NULL)&(curr.rChild=NULL) /如果左子右子都为空 printf(%d ,curr.data); /打印当前结点的内容 curr.data=0; /当前结点置空 void inOrder(Node *root) /中序遍历 Stack ms; /声明一个栈 Nod

20、e curr = *root; /当前结点指向根结点 int flag = 0; /设置一个标志 0:当前结点指向了右结点 1:当前结点指向了左结点 init(&ms); /初始化栈 while(curr.data!=0|isEmpty(ms) /当前结点不为空且栈不为空 if(curr.lChild!=NULL&flag=0) /左子不为空且没去过左子 push(&ms,curr); /当前子进栈 curr=*curr.lChild; /当前结点指向左子 else printf(%d ,curr.data); /打印当前结点的内容 if(curr.rChild!=NULL) /左子为空 cu

21、rr=*curr.rChild; /指向左子 flag=0; /flag 置 0 if(curr.rChild=NULL&curr.lChild=NULL) /如果左右子都为空 printf(%d ,curr.data); /打印当前结点的内容 if(isEmpty(ms)=1) break; /栈空 则结束循环 curr = pop(&ms); /当前子指向pop出栈的结点 flag=1; /flag 置 1 void postOrder(Node *root) /后序遍历 /声明左右栈 如果当前结点有左子则进左栈 若没左子但是有右子则进右栈 Stack msl; /声明左栈 MyStack

22、 msr; /声明右栈 Node curr = *root; /结点指向树的根结点 int flag=0; /设置一个标志 0:进左栈 1:进右栈 /设置一个标志 0:没去过左右子树 1:去过左子树 2:去过右子树(两子树都去过) int status=0; init(&msl); /初始化左栈 init(&msr); /初始化右栈 while(curr.data!=0|isEmpty(msl)!=0|isEmpty1(msr)!=0) /当前结点不为空且左右栈都不为空 if(status=0&curr.lChild!=NULL) /没去过左右子树 且右子不为空 push(&msl,curr)

23、; /当前子进左栈 curr = *curr.lChild; /当前子指向左子 flag=0; /flag置0 else if(status!=2&curr.rChild!=NULL) /没去过右子树且右子不为空 push1(&msr,curr); /当前子进右栈 curr=*curr.rChild; /当前子指向右子 flag=1; /flag置1 status=0; /status 置0 else printf(%d ,curr.data); /打印当前结点内容 curr.data=0; /当前结点置空 if(curr.data=0) /如果当前子为空 if(flag=0) /如果flag

24、标志为0 if(isEmpty(msl)=0) /如果左栈不为空 curr = pop(&msl); /指向左栈弹出的元素 status=1; /status标志置为1 else if(isEmpty1(msr)=0) curr = pop1(&msr); /指向右栈弹出的元素 status=2; /status标志置为2 else if(isEmpty1(msr)=0) /如果右栈为空 curr=pop1(&msr); /指向右栈弹出的元素 status=2; else if(isEmpty(msl)=0) curr=pop(&msl); /指向左栈弹出的元素 status=1; /stat

25、us标志置为1 if(curr.data=0) break; /若当前结点为空,结束循环 void main() int Tree = 1,2,4,0,7,0,0,0,3,5,0,0,6,8,0,0,9,0,0; int *tree = Tree; Node *root = buildTree(tree); /创建一个结点指向创建的树的根结点 printf(用非递归方法 n前序遍历: ); /打印提示内容 preOrder(root); /调用前序遍历函数 printf(n中序遍历: ); /打印提示内容 inOrder(root); /调用中序遍历函数 printf(n后序遍历: ); /打印提示内容 postOrder(root); /调用后序遍历函数 getch();四、运行结果图5 递归算法运行结果图 图6 非递归算法运行结果图五、遇到的问题及解决这部分我主要遇到了如下两个问题,其内容与解决方法如下所列: 二叉树的建立在刚开始进行时,如何建立二叉树难住了我,上课

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1