首页 > 编程知识 正文

二叉树的三种遍历详解,二叉树的先序,中序,后序遍历

时间:2023-05-03 18:09:22 阅读:34473 作者:2004

二叉树是重要的数据结构,也对二叉树的遍历很重要。 这里简要介绍在三种二叉树中顺序扫描的方法。 二叉树的中序扫描是首先扫描左子树,然后访问当前节点,最后扫描右子树。 在接下来的二叉树的情况下,中顺扫描的结果如下。

结果: [5、10、6、15、2]

直观上,二叉树的中序遍历是将节点投影到水平坐标上。 图:

1、递归法

这是思路最简单的方法,容易思考,容易实现。 递归终止条件是当前节点是否为空。 递归调用首先遍历左子树,然后访问当前节点,最后递归调用遍历右子树。 代码如下。

//recursiveclasssolution1{ public : vectorintinordertraversal (treenode * root ) { vectorint ret; if (根==空)返回ret; 在订单帮助器(ret,root ); 返回ret; } private 3360 voidinorderhelper (vectorintret,TreeNode* root ) if ) root==null ) return; 节点帮助器(ret,root-left ); ret.push _ back (根val; norderHelper(ret,root-right ); };

2、迭代法

迭代方法从根节点中查找二叉树的最左节点,将行走的节点保存在一个堆栈中,找到最左节点进行访问。 对于每个节点来说,它是以自己为根的子树的根节点,访问结束后可以转移到右儿子。 代码如下。

//iterate,usingastackclasssolution2{ public : vectorintinordertraversal (treenode * root ) { vectorint ret; if (根==空)返回ret; TreeNode *curr=root; 堆叠趋势科技* ST; while (! ST.empty(||curr!=null(while(curr!=NULL () ST.push ) ) curr; curr=curr-left; } curr=st.top (; st.pop (; ret.push_back(curr-val; curr=curr-right; }返回ret; }; 该方法的时间复杂度为o(n ),空间复杂度也为o(n )。

3、Morris法

这个方法是Morris发明的,看完之后,感觉很精妙。 该方法不使用递归,不使用堆栈,以o(1)的空间复杂度完成二叉树的遍历。 该方法的基本思想是将所有右儿子为NULL的节点的右儿子指向继承节点(对于右儿子不为空的节点,右儿子是下一个访问的节点)。 这样,对于任意一个节点,访问它之后,其右儿子已经指向下一个应该访问的节点。 在最右边的节点上,不需要这样的操作。 请注意,此操作在遍历过程中进行,并且在完成对节点的访问后将恢复树。 整个循环的判定条件是当前节点是否为空。 例如,在以上二叉树中,扫描过程如下(取决于当前节点c的位置)。

)1)当前节点为10,左儿子不为空,无法访问。 找到c左边子树的最右边节点p。

结果: []

)查找节点c左子树最右边的节点有两个退出条件。 一个右边的儿子是空的,另一个右边的儿子指向当前节点。 接下来是右边儿子为空的情况。 在这种情况下,首先将节点p的右儿子构建为指向后续节点c,然后将c下移。

结果: []

)3)当前节点c的左儿子为空,进入。 访问后,将c指向右儿子,即后继节点:

结果: [5]

)4)继续寻找左子树的最右边节点。 这次的结束条件是最右节点是当前节点。 这表示当前节点左侧的子树遍历完成,访问当前节点,然后恢复二叉树,将当前节点指向后续节点。

结果: [ 5,10 ]

)5)重复上述过程,直到c指向二叉树整体的最右边节点。

左儿子是空的,进行访问,c搬到右儿子。 右儿子为空,不符合判断条件,循环结束,遍历完成。 结果如下。

[5、10、6、15、2]

这就是Morris法,时间复杂度为o(n ),空间复杂度为o(n)。 代码如下。

//Morris traversal,withoutastackclasssolution3{ public : vectorintinordertraversal (treenode * root ) { vectorint ret; if (根==空)返回ret; TreeNode *curr=root; TreeNode *pre; while(curr ) if ) curr-left==null ) ret.push _ back (curr-val ); curr=curr-right; } else { pre=curr-left; 预光预光!=curr(pre=pre-right; if (前光==null ) {前光=curr; curr=curr-left; }else{ret.push_back(curr-val ); 前光=空值; curr=curr-right; } }返回ret; };

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。