树的非递归前、中、后序遍历
树的递归方法是比较简单的,但是非递归方法确实比较难写和理解的。
首先说下非递归方法的前序遍历:
使用栈来记录所走过的路程,前需遍历是 根节点开始往右边走,一直左,走到头了,才返回看看有没有右,如果有,走完右之后就继续往左走。
网上有很多版本的前序、中序遍历和后序遍历的的答案,代码也不相同,逻辑很简单,实现起来就多种多样,本文就展示一个最容易记忆的递归。
前序遍历和中序遍历走的路径是一样的。
但两者记忆路径的方式是不一样的,一个是在入栈的时候记路径
一个是在出栈的时候记路径
if(root!=null){
stack.add(root);
root = root.left;
}else{
// 弹出上一个节点的值
root = stack.pop();
// 此时走右边;
root= root.left
}
代码如下:
后续遍历技巧: 后续遍历的内容
如果有个树结构是 [1,2,3,4,5,6,7] 其后续遍历就是 :4,5,2,6,7,3,1
其镜像的前序遍历为 :1,3,7,6,2,5,4
因此我们把一个问题转化为另外一个问题了。
此时我们可以手动写下两种前序遍历:
1. 如上所示:
经过简单改变变成镜像的前序遍历,先走右边,再走左边
if(root!=null){
//进入之前记录进入的数组
stack.add(root);
root = root.right;
}else{
// 弹出上一个节点的值
root = stack.pop();
// 此时走左边;
root= root.left
}
将记录入栈的结果反转就可以了,你用另外一个栈记录也行。
2. 方法:
这是先序遍历非递归的另外一种写法:
这种虽然有弹栈的操作,走的路径不一样罢了,是先将右边的入栈,然后再入左边的。
此时稍加改造
说明前序遍历很重要,学会了前序遍历就相当于学会了后序遍历和中序遍历。