在Java中,先构造出一个树的节点类,这是进行树的相关操作最开始部分,节点类中应该包含节点的下标,数据域,然后就是指向该节点的父节点,左孩子节点和右孩子节点指针,这里说指针并不是太贴切,因为Java中并没有指针的概念,所以这里应该说是引用对象比较合适。当然为了防止变量被随意修改,我们最好申明为private,并添加相应的get和set方法,最后添加上构造方法,节点类完成:
public class TreeNode<T> {
private int index;//节点下标
private T data;//节点的数据域
private TreeNode leftChild;
private TreeNode rightChild;
private TreeNode parent;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public TreeNode(int index, T data){
this.index = index;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
}
现在节点类已经构建完毕,那么如何通过这个类来搭建一个二叉树呢?方法有很多,这里我们选取通过前序遍历数据序列反向生成二叉树的方法构建一个二叉树(数据结构中,二叉树的常用遍历方式有前序遍历、中序遍历和后序遍历方式)。
假设要搭建如下的二叉树:
如果通过前序遍历的方式,那么顺序应该是ABDECF,我们可以按此顺序将其放入一个集合中,然后依次读出并用于构建二叉树。
以上方法存在一个问题,那就是当我们读取出节点D之后,下一个读取的节点E应该是B的右孩子,那么我们怎么才能使程序知道E是节点B的右孩子而不是节点D的左孩子呢?一个巧妙的方法可以使我们很好地解决这个问题,那就是加入标记,即将上图中的二叉树变成如下:
那么现在二叉树的前序遍历方式为ABD##E##C#F##,当程序读到“#”时,便知道上一节点的左孩子或者右孩子已经为空,即没有左孩子或者右孩子,程序将停止继续为此节点添加左孩子或者右孩子。
public class BinaryTree {
private TreeNode root = null;//只存头结点
public void creatBinaryTreePre(ArrayList<String> data){
creatBinaryTree(data.size(),data);
}
private TreeNode creatBinaryTree(int size, ArrayList<String> data) {
if(data.size() == 0)
return null;
String d = data.get(0);
TreeNode node;
int index = size - data.size();
if(d.equals("#")){
node = null;
data.remove(0);
return node;
}
node = new TreeNode(index,d);
if(index == 0){
root = node;//创建根节点
}
data.remove(0);
node.leftChild = creatBinaryTree(size,data);
node.rightChild = creatBinaryTree(size,data);
return node;
}
}
我们可以编写一个前序遍历的代码来验证二叉树是否被正确建立:
public void preOrder(TreeNode node){
if(node == null){
return;
}
else{
System.out.println("preOrder data: "+node.getData());
preOrder(node.leftChild);
preOrder(node.rightChild);
}
}
测试代码如下:
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
String[] dataArray = new String[]{"A","B","D","#","#","E","#","#","C","#","F","#","#"};
ArrayList<String> data = new ArrayList<>();
for (String s : dataArray) {
data.add(s);
}
binaryTree.creatBinaryTreePre(data);
binaryTree.preOrder(binaryTree.root);
}
测试结果: