二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的。二叉树有前、中、后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的)。下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍历方式的非递归实现--基于Java实现的。
//package com.xforg.dataStructure;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * Created by Administrator on 2016/9/5.
 * By XFORG
 */

class TreeNode{// 节点的定义
    int value;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int value){
        this.value = value;
    }
}
/**
 * 二叉树的前序遍历的递归调用 --- 根节点 -- 左孩子--右孩子
 * 该方法很简单,根据需要遍历节点的顺序,递归的将遍历到的节点值放入list中。
 * 即:每次递归都是先放头结点,再遍历左子树,最后是右子树。
 * 递归调用简单,当是当节点过多时,其效率就会很差,而且比较耗费空间
 * Created by Administrator on 2016/9/5.
 */

/*public class BinaryTree {
    public static void fun(TreeNode pHead){
        ArrayList<Integer> list = new ArrayList<>();
        if(pHead != null){
            list.add(pHead.value);
        }
        if(pHead.left != null)
            fun(pHead.left);
        if(pHead.right != null)
            fun(pHead.right);
    }
}*/

/**
 * 二叉树的中序遍历的递归调用 --- 左孩子 -- 根节点--右孩子
 */
/*public class BinaryTree{
    public static void fun(TreeNode pHead){
        ArrayList<TreeNode> list = new ArrayList<TreeNode>();
        while(pHead != null){
            if(pHead.left != null)
                fun(pHead.left);
            list.add(pHead);
            if(pHead.right != null)
                fun(pHead.right);
        }
    }
}*/

/**
 * 二叉树的后序遍历的递归调用 --- 左孩子-- 右孩子--根节点
 */

/*public class BinaryTree{
    public static void fun(TreeNode pHead) {
        public static void fun(TreeNode pHead){
                ArrayList<TreeNode> list = new ArrayList<TreeNode>();
             while(pHead != null){
                 if(pHead.left != null)
                     list.add(pHead.left);
                 if(pHead.right != null)
                     list.add(pHead.right);
                 list.add(pHead);
             }
        }
    }
}*/

/**
 * 二叉树的前序遍历的非递归实现--- 根节点 -- 左孩子--右孩子
 *先访问根节点 再访问左子树,最后访问右子树。而对于每个子树来说,又按照同样的访问顺序进行遍历。
 * Created by Administrator on 2016/9/5.
 */

public class BinaryTree{
    public static void fun(TreeNode pHead){
            Stack<TreeNode> stack = new Stack<TreeNode>();
            Queue<Integer> q = new LinkedList<Integer>();//用来存放遍历的结果
            TreeNode pCur = pHead;
            TreeNode node = null;
            //当前节点非空或者Stack非空时执行
            while(pCur != null || !stack.isEmpty()){
                  q.add(pCur.value);//简单的观察一下程序结构,会发现每次入栈元素都为当前的“根节点”---而入栈的顺序是根节点,左子节点,右子节点。
                  stack.push(pCur);
                  pCur=pCur.left;
                while(pCur == null && !stack.isEmpty()){
                      pCur = stack.peek();
                      node = stack.pop();
                      pCur=pCur.right;
                }
            }
             for(Integer i : q)
            System.out.print(i+" ");
    }
    public static void main(String[] args){
        TreeNode t1= new TreeNode(1);
        TreeNode t2= new TreeNode(2);
        TreeNode t3= new TreeNode(3);
        TreeNode t4= new TreeNode(4);
        TreeNode t5= new TreeNode(5);
        TreeNode t6= new TreeNode(6);
        TreeNode t7= new TreeNode(7);
        t1.left=t2;
        t1.right=t3;
        t2.left=t4;
        t2.right=t5;
        t3.left=t6;
        t3.right=t7;
        t4.left =null;
        t4.right=null;
        t6.left=null;
        t6.right=null;
        t7.left=null;
        t7.right=null;
        fun(t1);
    }
}

/**
 * 二叉树的中序遍历的非递归实现--- 左孩子-- 根节点 --右孩子
 */
/*public class BinaryTree{
    public static void fun(TreeNode pHead){
           Stack<TreeNode> stack = new Stack<TreeNode>();
           Queue<Integer> q = new LinkedList<Integer>();
           TreeNode pCur = pHead;
           TreeNode node = null;
        while(pCur != null || !stack.isEmpty()){
            stack.push(pCur);
            pCur=pCur.left;
            while(pCur == null && !stack.isEmpty()){
                  pCur = stack.peek();
                  node = stack.pop();
                  q.add(node.value);//观察会发现,先序和中序唯一不同之处就在这条语句的位置。。。。。q中存储的是出栈元素。
                  pCur = pCur.right;
            }
        }
        for(Integer i : q)
            System.out.print(i+" ");
    }
    public static void main(String[] args){
        TreeNode t1= new TreeNode(1);
        TreeNode t2= new TreeNode(2);
        TreeNode t3= new TreeNode(3);
        TreeNode t4= new TreeNode(4);
        TreeNode t5= new TreeNode(5);
        TreeNode t6= new TreeNode(6);
        TreeNode t7= new TreeNode(7);
        t1.left=t2;
        t1.right=t3;
        t2.left=t4;
        t2.right=t5;
        t3.left=t6;
        t3.right=t7;
        t4.left =null;
        t4.right=null;
        t6.left=null;
        t6.right=null;
        t7.left=null;
        t7.right=null;
        fun(t1);
    }
}*/