二叉树的遍历用递归实现起来比较简单,用循环来实现的话则需要用到辅助栈。这其中前序遍历和中序遍历又相对容易实现,网上能找到较详细的介绍,这里就不再赘述了。后序遍历由于遍历父节点是在遍历子节点之后,而且左节点和右节点遍历后的行为不一样,所以它的循环实现则要复杂一些。网上也有实现的代码,不过都比较复杂难懂,在这里我用一个比较简单易懂的方法来实现。
首先看下后序遍历的定义:若二叉树非空,则依次执行如下操作: (1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。
和前序遍历的定义对比一下:若二叉树非空,则依次执行如下操作:(1) 访问根结点;(2) 先序遍历左子树;(3) 先序遍历右子树。
是否有什么发现?是的,如果把前序遍历的第2步和第3步互换一下,则正好的后序遍历的步骤完全相反!方便起见,我把它命名为逆后序遍历,它的定义:
若二叉树非空,则依次执行如下操作:(1) 访问根结点;(2) 逆后序遍历右子树;(3) 逆后序遍历左子树。
那么逆后序遍历的结果是否也和后序遍历的结果正好相反呢,我们来验证一下:
上图的二叉树后序遍历的结果是G D B F K C A, 逆后序遍历的结果是A C K F B D G,正好相反。也就是说,只要我们能实现逆后序遍历,再将遍历结果倒置一下,就是后序遍历了。那么如何实现逆后序遍历呢,其实逆后序遍历只是将前序遍历的第2步和第3步互换了一下,只要你能实现前序遍历,一切就很简单了。
前序遍历的代码如下:
public void preOrderTraverse(BinaryTreeNode root){
BinaryTreeNode temp=root;
Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();
while(!stack.isEmpty()||temp!=null){
if(temp!=null){
System.out.print(temp.data);
stack.push(temp);
temp=temp.leftChild; //访问左子树
}else{
temp=stack.pop();
temp=temp.rightChild; //访问右子树
}
}
}只要我们将访问左子树和访问右子树的语句对换一下位置,就是逆后序遍历了。接下来怎么将逆后序遍历的结果倒置呢,你是否想到了?对的,用栈,代码如下:
public void postOrderTraverse(BinaryTreeNode root){
BinaryTreeNode temp=root;
Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();
Stack<BinaryTreeNode> output=new Stack<BinaryTreeNode>();
while(!stack.isEmpty()||temp!=null){
if(temp!=null){
output.push(temp);
stack.push(temp);
temp=temp.rightChild;
}else{
temp=stack.pop();
temp=temp.leftChild;
}
}
while(!output.isEmpty()){
System.out.print(output.pop().data+" ");
}
}
呵呵,很简单吧!
转载于: http://hi.baidu.com/8qianyun/item/bf61f3dc390a7df493a97434