实现一颗树,采用数组的存储方式,将树中的节点用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> {
- 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;
- 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")
- 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);
- Arrays.fill(nodes, null);
- 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();
- }
- }