用Java描述数据结构之二叉树,前序遍历,中序遍历,后序遍历这篇博客中我介绍了二叉树的相关概念和递归实现的二叉树的前中后序遍历。今天来介绍非递归迭代版遍历的思路及实现代码。
首先我们要明白所谓遍历就是集合中每个节点都要经过,就下面这棵树而言,我们从根节点开始要怎么走才能经过每个节点?
下面是上图树的构建代码:
public static TreeNode buildTree() {
// 博客中所用到的树的构建
TreeNode a = new TreeNode('a');
TreeNode b = new TreeNode('b');
TreeNode c = new TreeNode('c');
TreeNode d = new TreeNode('d');
TreeNode e = new TreeNode('e');
TreeNode f = new TreeNode('f');
TreeNode g = new TreeNode('g');
TreeNode h = new TreeNode('h');
a.left = b; a.right = c;
b.left = d; b.right = e;
c.left = f; c.right = g;
e.right = h;
return a;
}
很明显我们要从根节点出发,左右都可以走,一般我们习惯往左走,我们一路向左走,直到走到没路可走,即cur == null,用代码实现这个是这样的:
//root为根节点
Treenode cur = root;
while(cur != null){
cur = cur.left;
}
直到我们走到空之后,下一步该怎么办?
每个节点都有左右两个方向可走,我们选择一路向左,走到头之后我们应该退一步,然后向右走,然后再向左走,再走到尽头,往回走,向右走一步。。。。。。。就这样去探路。拿例子来演示如下:
从A出发向左走,到尽头之后退一步到B往B的右边走一步到E,继续向左走,走到头之后退一步到E,再向右走到H,继续向左走,走到尽头之后退一步。。。。。。
我们把上述过程中的退一步称为回溯,想要实现回溯我们就必须从刚开始向左走的过程中记录经过的每个节点,而这个回溯很明显具有后入先出的特性,这让我们想到用栈去记录(递归版遍历实际也是通过栈回溯,不过是java虚拟机栈,每一个栈帧都是以此方法的调用)每走到尽头之后回溯一个节点,然后往这个节点的右边走,就这样直到栈空了,也就遍历完了。代码实现如下:
TreeNode cur = root;
Stack<