第一种方式通过保存父节点的方式来实现树,该种方式的缺陷是每一个节点找到其父节点是比较方便的,但是找每一个节点的子节点是比较困难的,需要遍历整个数组。
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;
}
}
本文探讨了使用Java构建树结构的两种方法:一种是保存父节点的方式,这种方式使得节点查找父节点变得简单,但查找子节点需遍历整个数组,效率较低。
5394

被折叠的 条评论
为什么被折叠?



