二叉树的递归与非递归遍历
来源:互联网 发布:java filter过滤器实例 编辑:程序博客网 时间:2024/06/16 00:24
二叉树遍历是二叉树中最基本的问题,其实现的方法非常多,有简单粗暴但容易爆栈的递归算法,还有稍微高级的使用栈模拟递归的非递归算法,另外还有不用栈而且只需要常数空间和线性时间的神奇Morris遍历算法,本文将对这些算法进行讲解和实现。
递归算法
二叉树节点使用以下数据结构进行表示,包括关键字、左儿子、右儿子属性和一个带默认参数的构造函数。
struct成员的默认属性为public,于是可以直接访问。
二叉树的递归算法非常简单,设置好递归出口之后,根据遍历的顺序,对当前节点的左右子递归调用自身即可。其前序、中序、后序遍历的代码如下。
栈模拟非递归算法
递归算法的本质是利用函数的调用栈进行,实际上我们可以自行使用栈来进行模拟,这样的算法空间复杂度为O(h),h为二叉树的高度。
前序遍历
首先把根节点入栈,然后在每次循环中执行以下操作:
- 此时栈顶元素即为当前的根节点,弹出并打印当前的根节点。
- 把当前根节点的右儿子和左儿子分别入栈(注意是右儿子先入栈左儿子后入栈,这样的话下次出栈的元素才是左儿子,这样才符合前序遍历的顺序要求:根节点->左儿子->右儿子)。
下面是代码实现。
后序遍历
因为后序遍历的顺序是:左子树->右子树->根节点,于是我们在前序遍历的代码中,当访问完当前节点后,先把当前节点的左子树入栈,再把右子树入栈,这样最终得到的顺序为:根节点->右子树->左子树,刚好是后序遍历倒过来的版本,于是把这个结果做一次翻转即为真正的后序遍历。而翻转可以通过使用另外一个栈简单完成,这样的代价是需要两个栈,但就复杂度而言,空间复杂度是O(n)。
中序遍历
中序遍历稍微复杂,使用一个指针p指向下一个待访问的节点,p初始化为根节点。在每次循环中执行以下操作:
- 如果p非空,则把p入栈,p变为p的左儿子。
- 如果p为空,说明已经向左走到尽头了,弹出当前栈顶元素,进行访问,并把p更新为其右儿子。
下面是代码实现。
0 0
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树 递归 与 非递归 遍历
- 递归与非递归二叉树遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 遍历二叉树(递归与非递归)
- 二叉树遍历的递归与非递归版本
- 遍历二叉树的递归算法与非递归算法
- JQuery数字类型验证正则表达式
- 智力推理:三个孩子的年龄分别是多少?
- Linux信号列表详解
- Dozer--第三方复制工具,哎哟,还不错!
- 【百度】BUG经验
- 二叉树的递归与非递归遍历
- 细数广告定向
- MySQL数据库中的日期相关函数整理
- js模拟引入命名空间
- Web性能:Facebook团队关于缓存效率的实践
- sql两个字段相加减,第三个字段没有值的原因.
- 怎样设置ABBYY PDF Transformer+中PDF转换
- junit集成maven。 No SecurityManager accessible to the calling code, either bound to the org.apache.shir
- 自定义控件让TextView的drawableLeft与文本一起居中显示