第一種方式通過保存父節點的方式來實現樹,該種方式的缺陷是每一個節點找到其父節點是比較方便的,但是找每一個節點的子節點是比較困難的,需要遍歷整個數組。
import java.util.ArrayList;
import java.util.List;
//關於樹的建立,我們有兩種方式一個是通過保存子節點的位置的 方式一個是通過保存父節點的方式
public class TreeParent <E>{
// 定義一個子類
static class Node<T>{
T data;
int parent;
// 保存其父節點的位置
public Node(T data){
this.data = data;
}
public Node (T data, int parent){
this.data = data;
this.parent = parent;
}
public String toString (){
return "date:"+data+"parent:"+parent;
}
}
private final int SIZE = 100;
private int treeSize = 0;
private Node<E>[]nodes;
private int nodeNums;
// 以指定的根節點創建樹
public TreeParent (E data){
treeSize = SIZE;
nodes = new Node [SIZE];
nodes[0] = new Node<E>(data,-1);
nodeNums++;
}
// 以指定的的根節點和treeseize來創建一個樹
public TreeParent (E date,int treeSize){
this.treeSize = treeSize;
nodes = new Node [treeSize];
nodes[0] = new Node<E>(date,-1);
nodeNums++;
}
// 未指定節點添加子節點
public void addNode (E data, Node parent){
for (int i= 0;i<treeSize;i++){
if(nodes[i]!=null){
nodes[i] = new Node (data, pos(parent));
nodeNums++;
return;
}
}
throw new RuntimeException("該樹已滿無法插入數據");
}
// 判斷樹是否爲空
public boolean empty(){
return nodes[0] == null;
}
// 返回根節點
public Node<E> root (){
return nodes[0];
}
// 返回指定節點的父節點
public Node<E> parent(Node node){
return nodes[node.parent];
}
// 返回指定節點的所有子節點
public List<Node<E>>children (Node parent){
List<Node<E>> child = new ArrayList<TreeParent.Node<E>>();
for(int i= 0;i<treeSize;i++){
if(nodes[i].parent == pos(parent))
child.add(nodes[i]);
}
return child;
}
public int deep (){
int deep = 0;
for(int i=0;i<treeSize && nodes[i]!= null;i++){
int def = 1;
int m = nodes[i].parent;
// nodes[m]可能會出現爲null嗎?
while (m!=-1 && nodes[m]!= null){
m = nodes[m].parent;
def++;
}
if(def>deep){
deep = def;
}
}
return deep;
}
// 返回包含指定值的節點,根據提供的節點,返回當前節點在當前數組所處的位置
public int pos (Node node){
for(int i= 0;i<treeSize;i++){
if(node == nodes[i])
return i;
}
return -1;
}
}
第二種方式保存子節點的方式
import java.util.ArrayList;
import java.util.List;
public class TreeChild <E>{
private static class SonNode{
private int data;
private SonNode next;
public SonNode (int data,SonNode next){
this.data = data;
this.next = next;
}
}
public static class Node<T>{
T data;
SonNode first;
// create a node
public Node(T data){
this.data = data;
this.first = null;
}
public String toString (){
return data+"";
}
}
private final int TREESIZE = 100;
private int treeSize = 0;
private Node []nodes;
private int nodesNum;
// create a tree
public TreeChild (E data){
treeSize = TREESIZE;
nodes = new Node[TREESIZE];
nodes[0] = new Node(data);
nodesNum ++;
}
public TreeChild (E data,int treeSize){
this.treeSize = treeSize;
nodes = new Node [treeSize];
nodes[0] = new Node (data);
nodesNum++;
}
// add a child node
public void addChild (E data ,Node parent){
for(int i= 0;i<treeSize;i++){
if(nodes[i]==null){
nodes[i] = new Node(data);
if(parent.first == null){
parent.first = new SonNode(i, null);
}
else {
SonNode next = parent.first;
while(next != null){
next = next.next;
}
next = new SonNode(i, null);
nodesNum++;
return;
}
}
}
}
public boolean empty (){
return nodes[0] ==null;
}
public Node <E>root(){
return nodes[0];
}
//accoring to an certain node to find all child node
public List <Node<E>> children (Node parent){
List<Node<E>> list= new ArrayList<Node<E>>();
SonNode next = parent.first;
while (next != null){
list.add(nodes[next.data]);
next = next.next;
}
return list;
}
//return index child node accoring to certain node
public Node<E>child (Node parent,int index){
SonNode next = parent.first;
for(int i = 0;next!=null;i++){
if(index == i)
return nodes[next.data];
next = next.next;
}
return null;
}
//cal deep of a tree
//涉及到遞歸調用的問題了,首先是判斷當前結點的子節點是否爲空,若爲空則直接返回1,如果不是空的話,我們就要對其所有的子節點進行一個遍歷,首先是判斷當前子節點的
//深度,如果當前結點還有子節點,那麼就繼續向下判斷,沒經過一次遞歸都會使當前的深度增加一
public int deep(Node node){
int max =0;
int deep = 0;
SonNode next = node.first;
if(next == null)
return 1;
while (next!=null){
max = deep(nodes[next.data]);
if(max >deep)
deep = max;
next = next.next;
}
return max+1;
}
}