1. 程式人生 > >java實現樹

java實現樹

實現一顆樹,採用陣列的儲存方式,將樹中的節點用Node類表示,方便與操作。
首先,整棵樹的陣列結構如下表所示,根節點的無父節點,用“-1”表示。
indexDataparent
0A-1
1B0
2C0
3D0
4E1
5F1
6G5

其次,定義一個節點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();
	}
}