//二叉树的定义
class BinaryTree {
int val;
BinaryTree LChild;
BinaryTree RChild;
public BinaryTree(){
;
}
public BinaryTree(int x){
val = x;
LChild = null;
RChild = null;
}
public BinaryTree create(int[] array){
if(array[0] == '*')
return null;
Queue<BinaryTree> queue = new ArrayDeque<>();
BinaryTree root = new BinaryTree(array[0]);
queue.add(root);
for(int i=0;i<array.length/2;i++){
if(queue.size()>0){
BinaryTree p = queue.remove();
if(array[2*i+1]!='*'){
p.LChild = new BinaryTree(array[2*i+1]);
queue.add(p.LChild);
}
if(array[2*i+2]!='*'){
p.RChild = new BinaryTree(array[2*i+2]);
queue.add(p.RChild);
}
}
}
return root;
}
public String toString(){
return val+"";
}
}
//先序遍历
思路:定义栈结构
1.根节点及所有左子树进栈,并且进栈的元素同时也访问
2.弹栈出来的元素,如果其右子树为空,则继续出栈,否则继续进栈并访问。
class PreOrderSearch {
BinaryTree root;
public PreOrderSearch(BinaryTree node){
root = node;
}
public List<BinaryTree> Pre(){
Stack<BinaryTree> stack = new Stack<>();
List<BinaryTree> list = new ArrayList<>();
BinaryTree p = root;
stack.add(p);
while(stack.size()>0){
while(p!=null){//左子树进栈同时访问之
stack.add(p);
list.add(p);
p = p.LChild;
}
while(stack.size()>0){
p = stack.pop();
if(p.RChild!=null){
p = p.RChild;
break;
}
p = null;//很关键!
}
}
return list;
}
}
//中序遍历
与先序类似
class InOrderSearch {
BinaryTree root;
public InOrderSearch(BinaryTree node){
root = node;
}
public List<BinaryTree> InOrder(){
Stack<BinaryTree> stack = new Stack<>();
List<BinaryTree> list = new ArrayList<>();
BinaryTree p = root;
while(p!=null||stack.size()>0){
while(p!=null){
stack.add(p);
p = p.LChild;
}
while(stack.size()>0){
p = stack.pop();//出栈之后再访问
list.add(p);
if(p.RChild!=null){
p = p.RChild;
break;
}
p = null;
}
}
return list;
}
}
//后序遍历
思路类似。
但后序遍历需要注意要记录上次访问过的节点,只有当节点的右孩子为空或者右孩子未被访问才能进栈。
class PostOrderSearch {
BinaryTree root;
public PostOrderSearch(BinaryTree node){
root = node;
}
public List<BinaryTree> PostOrder(){
Stack<BinaryTree> stack = new Stack<>();
List<BinaryTree> list = new ArrayList<>();
BinaryTree p = root;
BinaryTree temp = null;
while(p!=null||stack.size()>0){
while(p!=null){
stack.add(p);
p = p.LChild;
}
while(stack.size()>0){
p = stack.peek();
if(p.RChild!=null&&p.RChild!=temp){//需要注意的
p = p.RChild;
break;
}
else{
p = stack.pop();
list.add(p);
temp = p;//关键
}
p = null;
}
}
return list;
}
}
//测试程序
import java.util.*;
public class TestBinaryTree {
public static void main(String[] args) {
int[] data = {10,6,14,4,8,12,16};
BinaryTree root = new BinaryTree();
root = root.create(data);
PreOrderSearch preorder = new PreOrderSearch(root);
List<BinaryTree> list = preorder.Pre();
System.out.println(list.toString());
list = new InOrderSearch(root).InOrder();
System.out.println(list.toString());
list = new PostOrderSearch(root).PostOrder();
System.out.println(list.toString());
}
}