二叉树的遍历方式有两种:一种是比较简单的递归方式,另一种是借助栈实现的循环方式
1.先序遍历
a.先访问根节点
b.先序遍历左子树
c.先序遍历右子树
对应的递归算法:
public void preOrder(BNode root){
if(root==null) return;
else{
System.out.print(root.data+" ");
preOrder(root.left);
preOrder(root.right);
}
}
由先序遍历过程可知,先访问根节点,再访问左子树,最后访问右子树,因此,先将根节点进栈,在栈不空时:出栈node,访问node节点,再将其右孩子节点进栈,再将左孩子节点进栈。
public void preOrder1(BNode root){
Stack<BNode> st=new Stack<BNode>();
BNode node=root;
if(node!=null){
st.push(node); //根节点进栈
while(st.size()>0){ // 栈不为空时进行循环
node=st.pop(); //退栈并访问该节点
System.out.print(node.data+" ");
if(node.right!=null){ //有右孩子节点时,将右孩子压栈
st.push(node.right);
}
if(node.left!=null){ //有左孩子节点时,将左孩子压栈
st.push(node.left);
}
}
}
}
a.中序遍历左子树
b.访问根节点
c.中序遍历右子树
public void inOrder(BNode root){
if(root==null) return;
else{
inOrder(root.left);
System.out.print(root.data+" ");
inOrder(root.right);
}
}
先扫描(并非访问)根节点的所有节点并一一将它们压栈。然后出栈一个节点node,访问node。然后扫描该节点的右孩子节点,将其进栈,再扫描右孩子节点的所有做节点并一一进栈,这样直到栈空为止。
public void inOrder1(BNode root){
Stack<BNode> st=new Stack<BNode>();
BNode node=root;
while(node!=null || st.size()>0){
while(node!=null) { //将根节点的左孩子都一一压栈
st.push(node);
node=node.left;
}
if(st.size()>0){
node=st.pop(); //出栈一个节点
System.out.print(node.data+" ");
node=node.right;
}
}
}
3.后序遍历
a.后序遍历左子树
b.后序遍历右子树
c.访问根节点
public void postOrder(BNode root){
if(root==null) return;
else{
postOrder(root.left);
postOrder(root.right);
System.out.print(root.data+" ");
}
}
先扫描根节点的所有左节点并一一进栈,出栈一个节点node,然后扫描该节点的右孩子节点并进栈,再扫描右孩子节点的所有左孩子节点并进栈。当一个节点的左、右孩子节点均被访问过后,再访问该节点,如此这样,直到栈空为止。为了判断当前节点node的右孩子节点已被访问过,用q保存刚访问过的节点,若node.right==q成立,说明node的左右孩子节点均被访问过,现在该访问node节点了。
public void postOrder1(BNode root){
Stack<BNode> st=new Stack<BNode>();
BNode node=root;
BNode q; //记录之前遍历的右节点
int flag;
if(node!=null){
do{
while(node!=null){ //将根节点的左孩子都一一压栈
st.push(node);
node=node.left;
}
q=null; //q指向栈顶节点的前一个已访问的节点
flag=1; //flag=1表示处理栈顶节点
while(st.size()>0 && flag==1){
node=st.get(st.size()-1);
//如果右节点为空或右节点之前遍历过
if(node.right==null || node.right==q){
System.out.print(node.data+" ");
node=st.pop();
q=node;
}
else{
node=node.right;
flag=0; //flag=0表示栈顶节点处理完毕
}
}
} while(st.size()>0);
}
}