实现一颗树,采用数组的存储方式,将树中的节点用Node类表示,方便与操作。
首先,整棵树的数组结构如下表所示,根节点的无父节点,用“-1”表示。
Index Data Parent
0 A -1
1 B 0
2 C 0
3 D 0
4 E 1
5 F 1
6 G 5
其次,定义一个节点Node类,用来存储每个节点的内容
package my.tree;
public class Node<T> { //泛型<T>为Type,<E>为Element
private T data;
private int parent;
public Node(){
}
public Node(T data){
this.data = data;
}
public Node(T data,int parent){
this.data = data;
this.parent = parent;
}
public void setData(T data){
this.data = data;
}
public T getData(){
return this.data;
}
public void setParent(int parent){
this.parent = parent;
}
public int getParent(){
return this.parent;
}
}
开始实现树,提供基本的插入节点、获取所有节点、获取树的深度操作(着重)这些将数组大小设置为2,主要是考虑数组能否自动扩容;
package my.tree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MyTree<T> {
private final int DEFAULT_SIZE = 2;
private int size; //树的size
private int count; //节点个数
private Object[] nodes;
public MyTree() {
this.size = this.DEFAULT_SIZE;
this.nodes = new Object[this.size];
this.count = 0;
}
public MyTree(Node<T> root) {
this();
this.count = 1;
this.nodes[0] = root;
}
public MyTree(Node<T> root, int size) {
this.size = size;
this.nodes = new Object[this.size];
this.count = 1;
this.nodes[0] = root;
}
//添加一个节点
public void add(Node<T> node) {
for (int i = 0; i < this.size; i++) {
if (this.nodes[i] == null) {
nodes[i] = node;
break;
}
}
this.count++;
}
public void check(){
if(this.count >= this.size){
this.enlarge();
}
}
//添加一个节点,并指明父节点
public void add(Node<T> node, Node<T> parent) {
this.check();
node.setParent(this.position(parent));
this.add(node);
}
//获取节点在数组的存储位置
public int position(Node<T> node) {
for (int i = 0; i < this.size; i++) {
if (nodes[i] == node) {
return i;
}
}
return -1;
}
//获取整棵树有多少节点
public int getSize(){
return this.count;
}
//获取根节点
@SuppressWarnings("unchecked") //忽略unchecked警告
public Node<T> getRoot(){
return (Node<T>) this.nodes[0];
}
//获取所以节点,以List形式返回
@SuppressWarnings("unchecked")
public List<Node<T>> getAllNodes(){
List<Node<T>> list = new ArrayList<Node<T>>();
for(int i=0;i<this.size;i++){
if(this.nodes[i] != null){
list.add((Node<T>)nodes[i]);
}
}
return list;
}
//获取树的深度,只有根节点时为1
@SuppressWarnings("unchecked")
public int getDepth(){
int max = 1;
if(this.nodes[0] == null){
return 0;
}
for(int i=0;i<this.count;i++){
int deep = 1;
int location = ((Node<T>)(this.nodes[i])).getParent();
while(location != -1 && this.nodes[location] != null){
location = ((Node<T>)(this.nodes[location])).getParent();
deep++;
}
if(max < deep){
max = deep;
}
}
return max;
}
public void enlarge(){
this.size = this.size + this.DEFAULT_SIZE;
Object[] newNodes = new Object[this.size];
newNodes = Arrays.copyOf(nodes, this.size); //把nodes拷贝到newNodes,并确定size
Arrays.fill(nodes, null); //清空nodes
this.nodes = newNodes;
System.out.println("enlarge");
}
}
最后,使用MyTreeClient来测试下,基本功能是否都已经实现;
package my.tree;
public class MyTreeClient {
public static void main(String[] args){
Node<String> root = new Node<String>("A",-1);
MyTree<String> tree = new MyTree<String>(root);
Node<String> b = new Node<String>("B");
Node<String> c = new Node<String>("C");
Node<String> d = new Node<String>("D");
Node<String> e = new Node<String>("E");
Node<String> f = new Node<String>("F");
Node<String> g = new Node<String>("G");
tree.add(b,root);
tree.add(c,root);
tree.add(d,root);
tree.add(e,b);
tree.add(f,b);
tree.add(g,f);
System.out.println(tree.getSize());
System.out.println(tree.getRoot().getData());
System.out.println(tree.getAllNodes());
System.out.println(tree.getDepth());
tree.add(new Node<String>("H"),g);
System.out.println(tree.getDepth());
tree.enlarge();
}
}