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

来源:互联网 发布:苹果还是外星人 程序员 编辑:程序博客网 时间:2024/06/10 12:05

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

/*

参考博客:http://ocaicai.iteye.com/blog/1047397

*/

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();
    }
   
   
    }
}

0 0
原创粉丝点击