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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

二叉树递归非递归遍历.docx

1、二叉树递归非递归遍历数据结构算法设计学号:姓名: 专业班级: 成绩:评语:设计1:二叉树遍历设计要求:1. 根据二叉树遍历思想,分别实现先序遍历、中序遍历、后序遍历、层次遍历的算法2. 遍历算法可以尝试使用递归或非递归的方法实现。若需要使用堆栈或队列,请直接使用C+自带的stack和queue对象。设计分析(说明自己实现了哪几个算法,对每个算法的设计思想做简单扼要的说明)建立Tree类类中的元素有TreeNode *Root;/树的根节点bool Find;/查找开关bool Found;/判断是否找到指定编号的树叶int pos;/结点数量ElemType *data;/结点值的数组算法1.

2、先序遍历的递归实现(只需要写出核心代码和运行结果,对代码和结果做分析说明)算法代码:void Tree:PreOrder(TreeNode *t)/protected先序遍历输出树中所有的值 if(t) coutdata; PreOrder(t-LeftChild); PreOrder(t-RightChild); /if /PreOrder void Tree:PreOrder(bool enter)/public先序遍历 PreOrder(Root); if(enter)coutendl; /PreOrder调用代码:#define ElemType intint main() ElemT

3、ype data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeNode(t,5,true,NULL); T1.InitTree(data,9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.MakeNode(t,9,true,NULL); T1.insertLeftChild

4、(10,t); /在编号为10的树结点的左孩子插入数字9 T1.PreOrder(true); return 0;代码分析:代码的访问顺序:访问1,输出1;访问2,输出2;访问NULL(2的左孩子);访问3,输出3;访问5,输出5;访问9,输出9;访问NULL(9的左孩子);访问NULL(9的右孩子);访问NULL(5的右孩子);访问6,输出6;访问NULL(6的左孩子),访问NULL(6的右孩子);访问4,输出4;访问NULL(4的左孩子),访问NULL(4的右孩子);输出1235964运行结果:算法2.先序遍历的非递归实现算法代码:void Tree:Non_Recursive_PreOr

5、der(TreeNode*T) /protected非递归先序遍历 /* 首先进行p的输出。存储的内容基本上是右结点。 遍历左边缘不断输出,然后转到右结点入栈,继续 左边缘不断输出。等到再无左边缘的时候逆向输出 所有右孩子。 */ stack s; TreeNode *p=T,*q; s.push(p);/把Root推入栈内 while(!s.empty()/如果s不空 coutdata; q=p-RightChild; if(q)s.push(q); /如果q(p的右孩子)不空则将q推入栈 p=p-LeftChild; if(!p) /如果p(p的左孩子)为空则回到(p的右孩子) p=s.t

6、op(); s.pop(); /if /while /Non_recursive_PreOrder Status Tree:Non_Recursive_PreOrder(bool enter)/非递归先序遍历 Non_Recursive_PreOrder(Root); if(enter)coutendl; return OK; /Non_recursive_PreOrder调用代码:int main() ElemType data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeNode(t,5,true,NULL

7、); T1.InitTree(data,9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.MakeNode(t,9,true,NULL); T1.insertLeftChild(10,t); /在编号为10的树结点的左孩子插入数字9 T1.Non_Recursive_PreOrder(true); return 0;代码分析:不断遍历左孩子,如果有右孩子就

8、入栈。遍历到NULL的时候就读取栈首元素(即最近的一个右结点)。然后重复以上过程。访问1,输出1, 4入栈;访问2. 输出2, 3入栈;访问NULL,3出栈;访问3,输出3, 6入栈;访问5, 输出5;访问9; 输出9;访问NULL, 6出栈;访问6,输出6;访问NULL,4出栈;访问4, 输出4;运行结果:算法3 中序遍历的递归实现算法代码:void Tree:InOrder(bool enter)/public中序遍历 InOrder(Root); if(enter)coutLeftChild); coutdata; InOrder(t-RightChild); /if /InOrder调

9、用代码:int main() ElemType data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeNode(t,5,true,NULL); T1.InitTree(data,9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.MakeNode(t,9,true,NULL)

10、; T1.insertLeftChild(10,t); /在编号为10的树结点的左孩子插入数字9 T1.InOrder(true); return 0;代码分析:访问1;访问2,输出2;访问3;访问5;访问9,输出9;访问5,输出5;访问3,输出3;访问6,输出6;访问1,输出1;访问4,输出4;运行结果:算法4 中序遍历的非递归实现算法代码: Status Tree:Non_Recursive_IndexOrder(bool enter)/非递归中序遍历 Non_Recursive_IndexOrder(Root); if(enter)coutendl; return OK; /Non_re

11、cursive_IndexOrder void Tree:Non_Recursive_IndexOrder(TreeNode*T) /protected非递归中序遍历 /* 首先不断遍历左边缘但不输出只入栈, 直到碰到NULL后(此时p=NULL)返回父结点输出父结点。 然后转到右结点入栈,继续遍历左边缘不输出 只入栈。一直遍历到某个度为0的右结点的右孩子的时候 结束一支分支的遍历。 另一支分支的遍历相同。这一支分支的遍历 结束后中序遍历结束。 */ stack s; TreeNode *p=T; s.push(NULL); while(1) while(p) s.push(p); /栈是回溯

12、法的主要工具 p=p-LeftChild; /while 遍历左边缘直到NULL if(!s.top()break;/如果栈到达栈底则跳出 p=s.top();/p=NULL的时候返回其父结点或爷结点 s.pop();/弹出父结点 coutdata;/输出父结点 p=p-RightChild;/调用父结点的右孩子 /while /Non_recursive_IndexOrder调用代码:int main() ElemType data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeNode(t,5,true,NU

13、LL); T1.InitTree(data,9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.MakeNode(t,9,true,NULL); T1.insertLeftChild(10,t); /在编号为10的树结点的左孩子插入数字9 T1.Non_Recursive_IndexOrder(true); return 0;代码分析:入栈,访问左孩子,入栈

14、,访问左孩子。重复进行,一直到访问NULL。获得父节点(即栈首元素),并输出值,然后访问右结点,如果有,则重复以上过程。如果为NULL,则再次出栈输出值,继续访问右结点。访问1,入栈;访问2,入栈;访问NULL(2的左孩子),2出栈,输出2;访问3,入栈;访问5,入栈;访问9,入栈;访问NULL(9的左孩子),9出栈,输出9;访问NULL(9的右孩子),5出栈,输出5;访问NULL(5的右孩子),3出栈,输出3;访问6,入栈;访问NULL(6的左孩子),6出栈,输出6;访问NULL(6的右孩子),1出栈,输出1;访问4,入栈;访问NULL(4的左孩子),4出栈。输出4;访问NULL(4的右孩子

15、),栈空,跳出循环;运行结果:算法5 后序遍历的递归实现算法代码: void Tree:PostOrder(bool enter)/public后序遍历 PostOrder(Root); if(enter)coutLeftChild); PostOrder(t-RightChild); coutdata; /if /PostOrder调用代码:int main() ElemType data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeNode(t,5,true,NULL); T1.InitTree(data,

16、9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.MakeNode(t,9,true,NULL); T1.insertLeftChild(10,t); /在编号为10的树结点的左孩子插入数字9 T1.PostOrder(true); return 0;代码分析:访问1;访问2;访问NULL(2的左孩子);访问3;访问5;访问9;访问NULL(9的左孩子),

17、访问NULL(9的右孩子),输出9;访问5,访问NULL(5的右孩子),输出5;访问3,访问6,访问NULL(6的左孩子),访问NULL(6的右孩子),输出6;访问3,输出3;访问2,输出2;访问1,访问4,访问NULL(4的左孩子),访问NULL(4的右孩子),输出4;访问1,输出1;运行结果:算法6 后序遍历的非递归实现算法代码: Status Tree:Non_Recursive_PostOrder(bool enter)/非递归后序遍历 Non_Recursive_PostOrder(Root); if(enter)coutendl; return OK; /Non_Recursive

18、_PostOrdervoid Tree:Non_Recursive_PostOrder(TreeNode*T) /protected非递归后序遍历 /* 先进行左边缘遍历,入栈,并记载访问次数为1(tag=0)。 直到p=NULL,然后返回父结点,父结点访问次数为2(tag=1)。 p转到父结点的右孩子。 重复以上步骤。 如果栈顶结点被第三次访问,则输出该结点,弹出。 */ stack s;/用于存储树结点 stacks1;/用于存储结点暂离状态 TreeNode *p=T; s.push(NULL);/没有此句函数直接结束 while(1)/如果s不空 while(p) s.push(p);

19、 s1.push(false); p=p-LeftChild; /while 用于存储左边缘树结点,全部暂离 if(s1.top() p=s.top(); s1.pop(); s.pop(); coutdata; p=NULL; /if 第二次访问结点结点已待命,将结点和状态全部弹出,输出结点。令p=NULL,避免第四次读取结点。 else s1.pop(); s1.push(true); p=s.top()-RightChild; /else 如果结点是暂离,让其准备,当第二次碰见它时就输出。此时访问右孩子 if(!s.top()break;/如果栈到达栈底则跳出 /while /Non_r

20、ecursive_PostOrder调用代码:int main() ElemType data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeNode(t,5,true,NULL); T1.InitTree(data,9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.Make

21、Node(t,9,true,NULL); T1.insertLeftChild(10,t); /在编号为10的树结点的左孩子插入数字9 T1.Non_Recursive_PostOrder(true); return 0;代码分析:(第一次访问结点入栈状态为false,第二次访问结点将状态改成true,第三次访问结点输出结点数据,避免出现第四次访问结点。)(为什么是这样?访问父节点的时候设置状态为false,访问左孩子回到父节点状态改成true,从右孩子回到父节点的时候输出父节点,共三次。)非递归后序遍历的步骤:定义两个栈,第一个栈类型为 第二个栈类型为,以及树节点指针p,将NULL push

22、进栈。循环,如果p不为空,则(树节点栈)p入栈,(状态栈)false入栈,表示还没进行第二次访问。然后不断遍历左孩子。如果状态栈首元素为true(此时为第三次访问树节点),获得栈首树节点然后输出数据,出栈。 否则状态栈首元素为false(此时为第二次访问树节点),将状态改成false,然后访问其右孩子。如果到达栈底(NULL)就跳出无限循环。循环:访问1,1入栈,false入栈;访问2,2入栈,false入栈;访问NULL,跳出循环;由于栈首元素为false,false出栈,true入栈,然后访问2的右孩子; 循环:访问3,3入栈,false入栈;访问5,5入栈,false入栈;访问9,9入栈

23、,false入栈;访问NULL,跳出循环。由于栈首元素为false,false出栈,true入栈,然后访问9的右孩子 循环:NULL(9的右孩子),跳出循环由于栈首元素为true,9出栈,true出栈,输出9,然后(TreeNode*)p赋值为NULL; 循环:p为NULL,跳出循环。由于栈首元素是false,false换成true,访问5的右孩子;循环:访问NULL(5的右孩子),跳出循环;由于栈首元素是true,5出栈,true出栈,输出5,p=NULL;循环:访问NULL,跳出循环;由于栈首元素是false,false换成true,访问3的右孩子; 循环:访问6,6入栈,false入栈;

24、访问NULL(6的左孩子),跳出循环;由于栈首元素是false,false换成true,访问6的右孩子; 循环:访问NULL(6的右孩子),跳出循环;由于栈首元素是true,6出栈,true出栈,输出6,p=NULL;循环:NULL,跳出循环。由于栈首元素是true,3出栈,true出栈,输出3,p=NULL;循环:NULL,跳出循环。由于栈首元素是true,2出栈,true出栈,输出2,p=NULL; 十一:循环:NULL,跳出循环;false换成true;访问4十二:循环:4入栈,false入栈;NULL(4的左孩子),跳出循环;False换成true;访问NULL;十三:循环:NULL,

25、跳出循环;4出栈,true出栈,输出4,p=NULL;十四:循环:NULL,跳出循环;1出栈,true出栈,输出1,p=NULL;到达栈底,退出遍历。运行结果:算法7 层次遍历算法代码:void Tree:LevelOrder(TreeNode *t)/protected层次遍历 /* 读取每一层的时候把下一层存进队列中。 */ TreeNode *p=t; queueq; do if(p) coutdata; q.push(p-LeftChild); q.push(p-RightChild); /if p=q.front(); q.pop(); /do while(!q.empty(); /

26、LevelOrdervoid Tree:LevelOrder(bool enter)/public层次遍历 LevelOrder(Root); if(enter)coutendl; /LevelOrder调用代码:int main() ElemType data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeNode(t,5,true,NULL); T1.InitTree(data,9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.MakeNode(t,9,true,NULL); T1.insertLeftChild(10,t) /在编号为10的树结点的左孩子插入数字9 T1.LevelOrder(true); return 0;代码分析:运行结果:完整代码:#include#include#include#includequ

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

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