题目:用递归和非递归的形式实现二叉树的前中后序遍历

/*
*/
Java代码:
分了3个Java文件
Tree.java,TreeNode.java,TreeToSequence.java
TreeNode.java中
public class TreeNode
{
int val=0;
TreeNode  left=null;
TreeNode right=null;
pubic  TreeNode(int val)
{
this.val=val;
} 
}
Tree.java中
 import java.util.*; 



 public class Tree { 

   int [] arr={1,2,3,4,5,6,7,8,9}; 

    List<TreeNode> list=new LinkedList<TreeNode>(); 

    public void createTree() 

    { 

  for(int i=0;i<arr.length;i++) 

  { 

  list.add(new TreeNode(arr[i]));//将arr中的值建成树节点 

  }   

//头结点的下标为i,那么左右孩子的下标为2i+1,2i+2 

  for(int i=0;i<arr.length/2-1;i++)//前arr.length-1为父节点,后边都是叶子节点 

  { 

  //左孩子 

  list.get(i).left=list.get(2*i+1); 

  //右孩子 

  list.get(i).right=list.get(2*i+2); 

  } 

  //最后一个父节点可能没有右孩子,所以另外算 

  int j=arr.length/2-1; 

  list.get(j).left=list.get(2*j+1); 

  if(arr.length%2==1)//长度为奇数时才有右孩子 

  { 

  list.get(j).right=list.get(2*j+2); 

  } 

    } 

}


TreeToSequence.Java中
import java.util.*;


 public class TreeToSequence {
     public static int[][] convert(TreeNode root) {
         //二维数组形式是说,将先序,中序,后序一次输出,比如第一行是先序,第二行是后序,第三行是后序
         List<TreeNode> list1=new LinkedList<TreeNode>();
         List<TreeNode> list2=new LinkedList<TreeNode>();
         List<TreeNode> list3=new LinkedList<TreeNode>();
         pre(root,list1);
         mid(root,list2);
         pos(root,list3);
         int size=list1.size();
         int [][]res =new int[3][size];
         int []pre=new int[size];//用来存储先序遍历的值
         int []mid=new int[size];
         int []pos=new int[size];
         for(int i=0;i<size;i++)
             {
             pre[i]=list1.get(i).val;
             mid[i]=list2.get(i).val;
             pos[i]=list3.get(i).val;
         }
         res[0]=pre;
         res[1]=mid;
         res[2]=pos;
         return res;
     }
    
     /*//先序,为了后面能够用二维数组输出,先序遍历得到的值放到一个list中
     public static void pre(TreeNode node,List<TreeNode> list)
         {
         if(node ==null)
             {
             return;
         }
         list.add(node);//加入node这个节点。
         pre(node.left,list);
         pre(node.right,list);
     }
     //中序
     public static void mid(TreeNode node,List<TreeNode> list)
         {
         if(node==null) return;
         mid(node.left,list);
         list.add(node);
         mid(node.right,list);
     }
     //后序
     public static void pos(TreeNode node,List<TreeNode> list)
         {
         if(node==null) return;
         pos(node.left,list);
         pos(node.right,list);
         list.add(node);
     }
     */
     /*
     前序遍历
     1.申请一个新栈,将头结点压入栈中
     2.每次从栈中弹出栈顶元素cur,打印cur的值。如果cur的右孩子不为空的话,将cur的右孩子压入栈,如果cur的左孩子不为空,
     将cur的左孩子压入栈。都空或者都压入栈中了,那么将栈顶元素弹出
     3.不断重复2,直至栈空
     */
     public static void pre(TreeNode node,List<TreeNode> list)
         {
         if(node==null) return;
         Stack<TreeNode> st=new Stack<TreeNode>();
         TreeNode cur=null;
         st.push(node);
         while(!st.isEmpty())
             {
             cur=st.pop();
             list.add(cur);
             if(cur.right!=null)
                 st.push(cur.right);
             if(cur.left!=null)
                 st.push(cur.left);
         }
     }
     /*
 中序遍历
 1.建立一个新栈,和一个新变量cur初始值为头结点
 2.将cur入栈,将cur的所有左节点都入栈,cur=cur.left,直至cur为空
 3.弹出栈顶元素,记为node,如果node的右孩子存在,cur=node.right否则继续弹出栈顶元素
 4.一直重复2,3直至栈为空且cur为空
 */
 public static void mid(TreeNode node,List<TreeNode> list)
     {
     if(node==null) return;
     Stack<TreeNode> st=new Stack<TreeNode>();
     TreeNode cur=node;
     TreeNode point=null;
     st.push(node);
     while(!st.isEmpty()||cur!=null)
         {
         while(cur!=null)
             {
            st.push(cur);
             cur=cur.left;
         }
         point=st.pop();
         list.add(point);
         if(point.right!=null)
             {
             cur=point.right;
         }
     }
 }
   /*
   后序遍历,用1个栈实现
   1.新建一个栈,头结点压入栈中。2个变量h为最近一次弹出的节点,c为栈顶元素,不一定弹出。h初始值为头结点,c的初始值为null
   2.c为栈中栈顶元素,是否弹出根据以下情况来进行判断
   1)c的左孩子存在,且h不等于c的左孩子也不等于c的右孩子,那么把c的左孩子压入栈中
   2)在1)不成立时,c的右孩子存在,且h不等于c的右孩子,那么把c的右孩子压入栈中
   3)在1),2)都不成立时,将栈顶元素弹出并打印,然后h=c
   3.重复2,直至栈空
   */
     
     /*public void pos(TreeNode node,List<TreeNode> list)
         {
         if(node==null) return;
         Stack<TreeNode> st=new Stack<TreeNode>();
         TreeNode h=node;
         TreeNode c=null;
         st.push(node);
         while(!st.isEmpty())
             {
             c=st.peek();
             if(c.left!=null&&h!=c.left&&h!=c.right)
                {
                 st.push(c.left);
             } 
                 else if(c.right!=null&&h!=c.right)
                 {
                     st.push(c.right);
                 }
                 else
                {
                      list.add(st.pop());
                     h=c;
                 }
         }
     }*/
     
     /*
     后序遍历,用2个栈实现
     1.申请一个栈s1,把头结点压入栈中
     2.从s1中弹出节点记为cur,然后把cur的左孩子压入s1,然后把cur的右孩子压入s1.左右孩子都压入了或者为空,则将栈顶元素弹出
     3.在整个过程中s1中弹出的节点都压入s2中
     4.不断重复2,3直至s1为空
     5.最后将s2中节点依次出栈,并打印
     */
     public static void pos(TreeNode node,List<TreeNode> list)
         {
         if(node==null) return;
         Stack<TreeNode> s1=new Stack<TreeNode>();
         Stack<TreeNode> s2=new Stack<TreeNode>();
         s1.push(node);
         TreeNode cur=null;
         while(!s1.isEmpty())
             {
             cur=s1.pop();
             s2.push(cur);
             if(cur.left!=null)
                 {
                 s1.push(cur.left);
             }
             if(cur.right!=null)
                 {
                 s1.push(cur.right);
             }
         }
         while(!s2.isEmpty())
             {
             list.add(s2.pop());
         }
             
     }


     public static void main(String[] args)
     {
         Tree tr=new Tree();
     tr.createTree();
     TreeNode root=tr.list.get(0);
     int [][]res=new int[3][9];
     res=convert(root);
     for(int j=0;j<3;j++)
     {
     for(int i=0;i<9;i++)
         {
         System.out.print(res[j][i]+"  ");
         }
     System.out.println();
     }
     
     
     }
 }