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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

二叉树遍历C语言递归非递归六种算法Word下载.docx

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

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

3、代表左右子都去过,默认为0。第二个常量为 flag,取值为0或者1, 0代表进左栈,1代表进右栈。初始时指针指向根结点,判断根结点 是否有左子,有左子则,将根结点入左栈,status置0, flag置0,若没有左子则判断结点有 没有右子,有右子就把结点入右栈,status 10, flag It 1,若左右子都没有,则打印该结点, 并将指针指向空,此时判断flag,若flag为0,则从左栈出栈一个元素作为当前结点,重新 判断:若flag为1则从右栈出栈一个元素作为当前结点,重新判断左右子是否去过,若status 为1,则判断该结点有没有右子,若有右子,则将该结点入右栈,status 1, fl

4、ag置1,若 没有右子,则打印当前结点,并将指针置空,然后再次判断flag。若当前结点status为2, 且栈为空,则遍历结束。若指针指向了左子,则将左子作为当前结点,判断其左右子情况, 按上述方法处理,直至遍历结朿。二、算法流程图图1二叉树的建立用先序方法建立二叉树,为每个结点左义左右子,用0代表空,得到上述二叉树图2非递归二叉树遍历先序首先建立一个栈,当指针到达根结点时,打印根结点,判断根结点是否有左子和右子。 有左子和右子的话就打印左子同时将右子入栈,将左子作为新的根结点进行判断,方法同上。 若当前结点没有左子,则直接将右子打印,同时将右子作为新的根结点判断。若当前结点没 有右子,则打印

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

6、点,打印该结点, 然后判断flag, flag为1则将指针指向当前结点右子,将右子作为新的结点,结点入栈,再 次进行上而的判断,直至当前结点右子也为空,则再出栈一个元素作为当前结点,一宜到结图4非递归二叉树遍历后序第一个为status,取值为0, 1, 2.0代表左右子都没 有去过,1代表去过左子,2,代表左右子都去过,默认为0。第二个常疑为flag,取值为0 或者1, 0代表进左栈,1代表进右栈。初始时指针指向根结点,判断根结点是否有左子, 有左子则,将根结点入左栈,status置0, flag置0,若没有左子则判断结点有没有右子,有 右子就把结点入右栈,status 0, flag巻1,若

7、左右子都没有,则打印该结点,并将指针指 向空,此时判断flag,若flag为0,则从左栈出栈一个元素作为当前结点,重新判断;若flag 为1则从右栈岀栈一个元素作为当前结点,重新判断左右子是否去过,若status为1,则判 断该结点有没有右子,若有右子,则将该结点入右栈,status 1, flag置1,若没有右子, 则打印当前结点,并将指针置空,然后再次判断flag。若当前结点stauis为2,且栈为空, 则遍历结朿。若指针指向了左子,则将左子作为当前结点,判断其左右子情况,按上述方法 处理,直至遍历结朿。三、源代码下而给出的是用递归算法实现的程序的源代码:# include#include

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

9、苣当前结点的数据左子结点右子把创建的树的根肖点返回if(root!=0)printf(N%d *root-data); preOrder(root-lChild);rChild);void inOrder(Node *root)IinOrder(root-IChild);printf(n%d *root- inOrder(root-void postOrder(Node *root)(postOrdcr(root- postOrdcr(root- printf(N%d *root-如果根右点不为0/打印当前结点指向左子指向右子中序遍历如果根肖点不为0打印当前结点void main()按先序次序

10、输入树的结点(非0整数)来创建一个树空结点用0表示 int a = l,2,4Q7,0Q0.3,5Q068Q09Q0;int *b = a;将指向数组首地址的指针传给bulidTree函数来创建树Node *root = buildTree(b); printf(用递归方法nn前序遍历:”); preOrder(root);printf(Hii 中序遍历:”); inOrder(root);printf(n 后序遍历:); postOrder(root);getch();打印提示内容调用前序遍历函数/打印提示内容/调用中序遍历函数调用后序遍历函数下而给岀的是用非递归算法实现的程序的源代码:#i

11、ncludcs-bottom=(Node *)malloc( 100*sizeof(Node);/用非递归的方式遍历二叉树typedef struct nodestruct node *lChild,*rChild;typedef structNode *bottom;Node *top; Stack;void init(Stack *s)top=s-bottom;int isEmpty(Stack s)if(s.top=s.bottom)return 1;return 0;void push(Stack *s,Node node)*(s-top+)=node:Node pop(Stack *

12、s)Node node;node=*(-(s-top); return node;Node peek(Stack *s)return *(s-top-l);JMyStack;定义二叉树的结点/创建栈栈底指针栈顶指针初始化栈为指针开辟内存栈顶指针指向栈底指针判断栈是否为空的函数栈空返回1不为空返回0栈的push方法给栈顶赋值然后top+1出栈函数声明一 Node类型遍量/node为栈顶元素 然后top-1返回pop出的结点看栈顶元素/返回栈顶元素/创建栈(MyStack)结构体void initl(MyStack *s)void pushl(MyStack *s,Node node)top+)=

13、node;Node popl(MyStack *s)return node;Node peekl(MyStack *s)int isEmptyl(MyStack s)if(s.top=s.bottom) return 1;int temp=-l;Node *buildTrec(int *b)if(b+temp=0) p=NULL: p=(Node*)malloc zcof(Nodc);p-data=btemp;void preOrder(Nodc *root)Stack po;Node curr = *root;进栈方法给栈顶賦值然后top+1/node为栈顶元素然后top-1查栈顶元素判断栈

14、是否为空/栈空了返回1产生二叉树设置当前结点的数据把创建的树的根结点返回/前序遍历声明一个栈当前结点为根结点初始化找当前结点不为空且栈不为空如果当前结点为空当前结点指向pop出栈的结点如果右子为空将右子进栈/打印当前结点的内容如果左子不为空当前子指向左子当前子指向pop出栈结点如果左子右子都为空打印当前结点的内容当前结点置空当前结点指向根结点1:当前结点指向了左结点init(&ms);while(curr.data!=OllisEmpty(ms)if(curr.lChild!=NULL&flag=O) push(&ms,curr); curr=*curr.lChild;else%d ”,cur

15、r.data); if(curr.rChild!=NULL)/当前结点不为空且栈不为空左子不为空且没去过左子当前子进栈当前结点指向左子左子为空po);“h=OII!isEmpty(po) if(curr.data=O)curr=pop(& if(cunrChild!po,*cunrChild); printf(H%d curr.data); if(cunIChild!=NULL) curr=*curr.lChild;if(curr.lChild=NULL)&(curr.rChild=NULL) ( curr.data=O;Stack ms;int flag = 0;/设置一个标志0:当前结点指

16、向了右结点flag=O;if(cunrChild=NULL&ciHT.lChild=NULL)/flag 置 0如果左右子都为空printf(H%d .curr.data); if(isEmpty(ms)=l) break; curr = pop(&flag=l;/栈空则结束循环当前子指向pop出栈的结点/flag 置 1void postOrder(Node *root) 后序遍历声明左右栈如果当前结点有左子则进左栈若没左子但是有右子则进右栈Stack msl: 声明左栈声明右栈结点指向树的根结点MyStack msr; Node curr = * root;int flag=O;/设置一个

17、标志0:进左栈1:进右栈没去过左右子树1:去过左子树2:去过右子树(两子树都去过)初始化左栈初始化右栈int status=O; inil(&msl); init(&msr);=OllisEmpty(msl)!=OllisEmptyl(msr)!=O)/当前结点不为空且左右栈都不为空if(status=O&curr.lChild!m si,curr);curr = *curr.lChild;flag=0;else if(status!=2&curr.rChild!=NULL) (push 1(&m srxurr);curr=*curr.rChild;status=O;没去过左右子树且右子不为空

18、当前子进左栈/没去过右子树且右子不为空/当前子进右栈当前子指向右子/status 置 0printf(H%d *curr.data);打印当前结点内容如果当前子为空 如果flag标志为0如果左栈不为空指向左栈弹出的元素 /status标志置为1/指向右栈弹出的元素/status标志置为2如果右栈为空指向右栈弹出的元素指向左栈弹岀的元素 /status标志置为1若当前结点为空,结朿循环if(flag=O)if(isEmpty(msl)=O)curr = pop(& status=l;else if(isEmpty 1 (msr)=O) curr = pop 1(&m sr); status=2;

19、Jelseif(isEmpty 1 (msr)=0)curr=popl(&else if(isEmpty(msl)=O)if(curr.data=O) break;)int Tree = 124Q70.003,5Q06&009Q0;int *tree = Tree:Node *root = buildTree(tree);用非递归方法n前序遍历:printf(Hn 中序遍历: postOrdcr(root);创建一个结点指向创建的树的根结点 /打印提示内容调用中序遍历函数四、运行结果D:Usersy3cgDblaop新逹文舛夫6bug新建文本文栏exe用递归方搖前序遍历:124783569目1

20、274815369后序遍历:704259631.ak J图5递归算法运行结果图图6非递归算法运行结果图五、遇到的问题及解决这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:二叉树的建立在刚开始进行时,如何建立二叉树难住了我,上课时听老师讲的是java的,在建立 二叉树时和C语言不一样,在网上査阅了一部分资料后,找到了合适的办法,就是 用结构体来储存二叉树,结构体内左义了二叉树的值和左右子,用0代表null,这 样就可以用先序算法迪历输入了在进行非递归遍历时,编译不报错,但运行岀现下面的错误到网上查询后,得知出现“ Access Violation”错误,有两种可能,第一种:出现这 个错

21、误是因为试图访问一块已经被释放的内存,第二种是想使用一个还未创建对象 的指针。解决的办法是为指针分配内存,用(Nodc*)malloc(sizcof(Nodc)语句,这样 就能解决这个问题。六、心得体会大一就开始学习C语言,可是,当时学的时候就觉得语言好像是学会了,可是一遇到 编程的问题还是头大,总感觉没有什么思路,而这次作业,给自己一个不得不动手操作的机 会,在十一的这几天中,复习了以前学过的C的基本知识,然后一点一点的摸索,遇到了 错误和同学一起讨论,有问题自己想办法解决,最后程序调试出来的时候,会觉得貞的很高 兴。我知道,我们现在的水平还很差,要想学习好这门课,在以后就要多动手操作,书上的 例题或算法,最好都自己编写程序实现,那样可以加深对算法的理解,也可以提高我们编程 的水平。同时,很多的东西,理解了,可是在实现的时候还是有很多的错误发生,在以后的 练习和实践中,应该多动手,遇到问题多思考,即使方案不是最优的也要想办法自己解决, 然后和好的方案进行比较,从中找岀自己的差距在哪里。

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

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