您的位置:首页 > 其它

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

2016-07-15 19:29 344 查看
题目:用递归和非递归的形式实现二叉树的前中后序遍历

/*

参考博客: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);
  }

   }
}

TreeToSe
4000
quence.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();

    }

   

   

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息