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