在网上看了几个二叉树无递归无额外空间遍历的算法,感觉讲的太晦涩难懂,而递归遍历理解却非常容易,于是想着如果能和递归遍历一一对应起来,那么理解二叉树无递归无额外空间遍历的算法则容易许多了,而且理解会更加深入。
废话不多说,直接看代码和注释,一共没几行代码。
public class BinTree {
public void preSubNode(Node node) {
Node curNode = node;
while (true) {
if (curNode == null) {
//遍历到最后一个了,返回
return;
}
// 得到前驱节点
Node beforeNode = getBeforeNode(curNode);
if (beforeNode != null && beforeNode.getRight() == null) {
//相当于执行到刚进入递归方法的时候
//相当于将参数为当前节点的方法压入方法栈,保留当前地址到前驱节点的右孩子上,避免遍历完成后回不来
beforeNode.setRight(curNode);
//相当于递归调用当前节点的左孩子
curNode = node.getLeft();
} else {
//相当于执行完递归调用左孩子之后返回的时候,或者前驱节点为空,不需要递归调用左孩子的时候
//输出当前节点
System.out.println(curNode.getValue());
//相当于递归调用当前节点的右孩子,对于叶子节点,则是一直返回,直到是其后继节点的父节点,
//对于后序遍历,这一步不能直接返回,要顺着路径一级一级返回,返回一个输出一个。
curNode = curNode.getRight();
}
}
}
private Node getBeforeNode(Node node) {
//得到第一个左节点
Node curNode = node.getLeft();
if (curNode == null) {
return null;
}
//然后一直右节点
while (true) {
Node right = curNode.getRight();
if (right == null || right.equals(node)) {
return curNode;
}
curNode = curNode.getRight();
}
}
}