二叉树的遍历(堆栈) 爱被打了一巴掌 2023-05-28 12:56 1阅读 0赞 # 二叉树的遍历(堆栈) # **如何理解用堆栈方式代替递归去遍历二叉树,关键点在于了解每个结点输出时的顺序,以及理解前序中序后序是如何遍历的,这点很重要,可以自己画一个树图,熟练写出遍历的结果** ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MDY1NTg5_size_16_color_FFFFFF_t_70] 以上图为例,在进行先序遍历的时候,最先输出的是A,而在中序遍历的时候,A是在第四次时候才输出(DEBA) 以中序遍历为例子,我们要先遍历所有的左子树,把每个左子树上的结点存入堆栈中,然后再pop出堆栈里的结点,输出该结点,然后在判断该结点是否还有右儿子 下面的代码就是遍历所有的左子树上的结点存入堆栈中,然后依次pop出结点,判断当前结点是否存在右儿子 以上图为例,D结点虽然没有左儿子和右儿子了,但是在以链表来看,实际上D存在着为NULL的左儿子和右儿子,所以所有的叶子结点都存在值为NULL的左儿子和右儿子,E结点,F结点同理。 ,在第二层循坏While§循坏完后,当前结点是D的左儿子NULL,对于A来说 B是它的左儿子,A是根节点,同理 D此时并不是叶子结点,而是 两个NULL的根节点,通过pop取出D这一个根节点 然后判断D有没有右儿子,很明显是有一个NULL的右儿子,但是这只是对于链表的存储方式来说,在真正树状图上它是不存在右儿子的,你会发现最外层循坏语句 第二次循坏的时候,pop直接取出 了B,然后p=p->right,p指向B的右儿子E,所以可以把 语句理解为判断当前结点是否有右儿子结点,没有则输出当前结点的根节点,如果有的话继续对右边的结点进行操作 void firstoder(Tree p)//传送过来的二叉树 { PNode pile =createPNode();//创建一个堆栈pile while(p||!IsEmpty(pile)) { while(p)//遍历左子树上的结点 { push(pile,p); p=p->left;} if(!IsEmpty(pile)) { p=pop(pile); printf("%d ",p->date);//输出结点的值 p=p->right; } } } 先序遍历:看图可知,A B D都是相对于自己的左子树和右子树的根节点,比如 A就是 BDE的根节点,B就是DE的根节点,D就是NULL NULL的根节点,在先序遍历的时候,根节点是最先输出的 其次是左节点和右结点,,所以在循坏的时候,就要在循坏… 遍历左子树把每个左节点存入的堆栈的时候就要输出当前的结点,也就是只用移动一下输出语句的位置就能从中序变为先序 void firstoder(Tree p)//传送过来的二叉树 { PNode pile =createPNode();//创建一个堆栈pile while(p||!IsEmpty(pile)) { while(p)//遍历左子树上的结点 { push(pile,p); printf("%d ",p->date); p=p->left;} if(!IsEmpty(pile)) { p=pop(pile); p=p->right; } } } -------------------- -------------------- **接下来就是后序遍历**,后续遍历顺序是左 中 右,关键点在于 我们现在处于左结点,我们需要通过上一个头节点去访问跟我们现在的左节点同一层的右结点,去输出右节点,但此时头节点已经pop出来了,所以头节点无法再访问到了,所以我们需要把头节点的值保存下来,压栈进堆栈里。 void firstoder(Tree p)//传送过来的二叉树 { PNode pile =createPNode();//创建一个堆栈pile while(p||!IsEmpty(pile)) { while(p)//遍历左子树上的结点 { push(pile,p); printf("%d ",p->date); p=p->left;} if(!IsEmpty(pile)) { Tree temp=(Tree)malloc(sizeof(struct TreeNode));//创建临时指针存储头结点 p=pop(pile); temp=pop; p=p->right; temp->right=NULL;//遍历的指针指向当前结点的右儿子,把当前结点的右儿子设置NULL,防止死循环 if(p) push(pile,temp);//如果当前结点存在右儿子结点,那么存储当前结点,继续遍历右子树 else printf("%d ",temp->date);//当前结点没有右儿子,那么直接输出当前结点 } } } -------------------- ## 我是一个小萌新,第一次写博客,写的很渣,请见谅!— ## [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MDY1NTg5_size_16_color_FFFFFF_t_70]: /images/20230528/94bf15cee9de4d9682b59abc09d58515.png
相关 二叉树的遍历(堆栈) 二叉树的遍历(堆栈) 如何理解用堆栈方式代替递归去遍历二叉树,关键点在于了解每个结点输出时的顺序,以及理解前序中序后序是如何遍历的,这点很重要,可以自己画一个树图,熟练写 爱被打了一巴掌/ 2023年05月28日 12:56/ 0 赞/ 2 阅读
相关 二叉树 二叉树遍历 通过二叉树遍历求得二叉树 什么是二叉树 > > 二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且 偏执的太偏执、/ 2022年12月04日 01:08/ 0 赞/ 305 阅读
相关 遍历二叉树 1. 二叉树的遍历 遍历定义 ——顺着某一条搜索路径巡访二叉树中的结点,使得 每个结点均被访问一次,而且仅被访问一次。 “访问”的含义可以很广,如:输出结点的信息等。 迈不过友情╰/ 2022年08月22日 14:26/ 0 赞/ 439 阅读
相关 遍历二叉树 遍历二叉树 二叉树是由3个基本单元组成的:根结点、左子树和右子树。 若限定先左后右的顺序,则遍历二叉树只有三种情况分别称为先(根)序遍历、中(根)序遍历和后(根)序遍 比眉伴天荒/ 2022年06月08日 00:48/ 0 赞/ 304 阅读
相关 遍历二叉树 遍历二叉树 今天我们学习了二叉树,现在我就基于二叉树的递归定义来说一说遍历二叉树的三种方法:先序、中序和后序。 根据二叉树的递归定义可知,二叉树是由3个基本单元组成:根结点 傷城~/ 2022年06月05日 08:11/ 0 赞/ 352 阅读
相关 二叉树遍历 include<iostream> include<queue> using namespace std; //二叉树结点 ╰+攻爆jí腚メ/ 2022年06月04日 05:35/ 0 赞/ 301 阅读
相关 二叉树遍历 前序遍历(左中右)ABDGHCEIF ![前序遍历][70] 中序遍历(左根右)GDHBAEICF![中序遍历][70 1] 后序遍历(左右根)GHDBIEFCA![ Bertha 。/ 2022年05月11日 13:48/ 0 赞/ 360 阅读
相关 二叉树遍历 二叉树是数据结构中很重要的一个章节,很多同学反应很难,今天我就把我平时的经验给大家讲解一下,今天讲一下二叉树的遍历 工具/原料 ● 数据结构知识 ● 了解树的定义 爱被打了一巴掌/ 2022年05月10日 03:08/ 0 赞/ 318 阅读
相关 遍历二叉树 用递归的方法实现前序遍历,中序遍历,后序遍历: 用递归的方法遍历的时候,其实每个节点都遍历了三遍,根据打印时间的不同,即可实现前序中序及后续,这就是三个遍历代码一样而打印顺序 浅浅的花香味﹌/ 2021年11月01日 15:28/ 0 赞/ 467 阅读
还没有评论,来说两句吧...