二叉树的前序、中序、后序(递归、非递归)遍历java实现

前序遍历:中-左-右

中序遍历:左-中-右

后序遍历:左-右-中

树中的结点定义:

 static class Node{
Node leftChild;
Node rightChild;
int rvisited;
char data;
Node(char newData){
leftChild=null;
rightChild=null;
data=newData;
}
public Node(char data,Node leftChild, Node rightChild) {
super();
this.leftChild = leftChild;
this.rightChild = rightChild;
this.data = data;
}

      }

树的建立:

public static Node init() {  
       Node a = new Node(‘A’);  
       Node b = new Node(‘B’, null, a);  
       Node c = new Node(‘C’);  
       Node d = new Node(‘D’, b, c);  
       Node e = new Node(‘E’);  
       Node f = new Node(‘F’, e, null);  
       Node g = new Node(‘G’, null, f);  
       Node h = new Node(‘H’, d, g);  
       return h;// root  
   }  

前序遍历递归代码实现:

public static void preOrderTraverse(Node node){
if(node!=null){
System.out.print(node.data+” “);
preOrderTraverse(node.leftChild);
preOrderTraverse(node.rightChild);
}
}

前序遍历非递归代码实现:

  public static void iterativePreorder(Node p) {  
        Stack<Node> stack=new Stack<Node>();
        stack.push(p);
        while(!stack.empty()){
        Node temp=stack.pop();
        System.out.print(temp.data+” “);
        if(temp.rightChild!=null) stack.push(temp.rightChild);
        if(temp.leftChild!=null)  stack.push(temp.leftChild);
        }
    }  

中序遍历递归代码实现:

public static void inOrderTraverse(Node node){
if(node!=null){
inOrderTraverse(node.leftChild);
System.out.print(node.data+” “);
   inOrderTraverse(node.rightChild);
}
}

中序遍历非递归代码实现:

public static void iterativeInorder(Node p) {  
   Stack<Node> stack=new Stack<Node>();
   while(p!=null){
    stack.push(p);
    p=p.leftChild;
   }
   while(!stack.isEmpty()){
    Node node=stack.pop();
    System.out.print(node.data+” “);
    if(node.rightChild!=null){
    node=node.rightChild;
    while(node!=null){
       stack.push(node);
       node=node.leftChild;
    }
    }
   }
}

后序遍历递归代码实现:

public static void postOrderTraverse(Node node){
if(node!=null){
postOrderTraverse(node.leftChild);
postOrderTraverse(node.rightChild);
System.out.print(node.data+” “);
}
}

后序遍历非递归代码实现:

public static void iterativePostorder(Node p){
Stack<Node> stack=new Stack<Node>();

//首先,从根节点开始,往左下方走,一直走到头,将路径上的每一个结点入栈。

while(p!=null){

   stack.push(p);

//
push到栈中两个信息,一是结点指针,一是其右结点是否被访问过

   p=p.leftChild;

}

//然后进入循环体

while(!stack.isEmpty()){
//
只要栈非空

   Node node=stack.peek(); 

//
sn是栈顶结点

 //注意,任意一个结点N,只要他有左孩子,则在N入栈之后,N的左孩子必然也跟着入栈了(这个体现在算法的后半部分),所以当我们拿到栈顶元素的时候,可以确信这个元素要么没有左孩子,要么其左孩子已经被访问过,所以此时我们就不关心它的左孩子了,我们只关心其右孩子。
    //若其右孩子已经被访问过,或是该元素没有右孩子,则由后序遍历的定义,此时可以visit这个结点了。

   if(node.rightChild==null||node.rvisited==1){

       System.out.print(node.data+” “);

       stack.pop();

   }else{

//若它的右孩子存在且rvisited为0,说明以前还没有动过它的右孩子,于是就去处理一下其右孩子。
    { 
      //此时我们要从其右孩子结点开始一直往左下方走,直至走到尽头,将这条路径上的所有结点都入栈。

      //当然,入栈之前要先将该结点的rvisited设成1,因为其右孩子的入栈意味着它的右孩子必将先于它被访问(这很好理解,因为我们总是从栈顶取出元素来进行visit)。由此可知,下一次该元素再处于栈顶时,其右孩子必然已被visit过了,所以此处可以将rvisited设置为1。

   if(node.rightChild!=null){

   
node.rvisited=1;

 //往左下方走到尽头,将路径上所有元素入栈

   
node=node.rightChild;

   
while(node!=null){

   
  stack.push(node);

   
  node=node.leftChild;

   
}

   }

//这一轮循环已结束,刚刚入栈的那些结点我们不必管它了,下一轮循环会将这些结点照顾的很好。

   }

 }

 }  

点赞