1、树,指的是N个有父子关系的节点的有限集合。
2、树的有关术语:
节点:树的最基本组成单元
节点的度:节点拥有子树的个数
树的度:树中所有节点的度的最大值
节点的层次:从根开始算起,根的层次值为1,其余节点的层次值为父节点层次值加1
树的深度:树中节点的最大层次值称为树的深度或高度
有序树和无序树:如果将树中的节点的各个子树看成从左到右是有序的(即不能互换),则称该树为有序树,否则称为无序树
森林:森林是2棵或者2棵以上互不想交的树的集合,删去一棵树的根,就得到一个森林
以下是用父节点表示法实现一棵树:
import java.util.ArrayList;
import java.util.List;
/**
*父节点 表示法实现一棵数,父节点表示法就是记录每个节点的父节点是谁,用整数表示,根节点的父节点为-1
*
*/
public class TreeParent<E> {
public static class Node<T>{
T data;
int parent;//记录父节点的位置
public Node(){}//无参构造函数
public Node(T data){
this.data=data;
}
public Node(T data,int parent){
this.data=data;
this.parent=parent;
}
//重写toString()方法
public String toString(){
return "TreeParent$Node[data="+data+",oarent="+parent+"]";
}
}
private final int DEFAULT_TREE_SIZE=100;
private int treeSize=0;
private Node<E>[] nodes;//使用一个Node[]数组来记录该树里的所有节点
private int nodeNums;//记录节点数
//以指定根节点创建树
public TreeParent(E data){//
treeSize=DEFAULT_TREE_SIZE;
nodes=new Node[treeSize];
nodes[0]=new Node<E>(data,-1);
nodeNums++;
}
//以指定根节点、指定treeSize创建树
public TreeParent(E data,int treeSize){
this.treeSize=treeSize;
nodes=new Node[treeSize];
nodes[0]=new Node<E>(data,-1);
nodeNums++;
}
//为指定节点添加子节点
public void addNode(E data,Node parent){
for(int i=0;i<treeSize;i++){
//找到数组中第一个为null的元素,该元素保存新节点
if(nodes[i]==null){
//创建新节点,并用指定的数组元素保存它
nodes[i]=new Node(data,pos(parent));
nodeNums++;
return;
}
}
throw new RuntimeException("该树已满,无法添加新节点");
}
//判断树是否为空
public boolean empty(){
//根节点是否为null
return nodes[0]==null;
}
//返回根节点
public Node<E> root(){
//返回根节点
return nodes[0];
}
//返回指定节点(非根节点)的父节点
public Node<E> paren(Node node){
//每个节点的parent记录了其父节点的位置
return nodes[node.parent];
}
//返回指定节点(非叶子节点)的所有子节点
public List<Node<E>> children(Node parent){
List<Node<E>> list=new ArrayList<Node<E>>();
for(int i=0;i<treeSize;i++){
//如果当前节点的父节点的位置等于parent节点的位置
if(nodes[i]!=null&&nodes[i].parent==pos(parent)){
list.add(nodes[i]);
}
}
return list;
}
//返回该树的深度
public int deep(){
//用于记录节点的最大深度
int max=0;
for(int i=0;i<treeSize&&nodes[i]!=null;i++){
//初始化本节点的深度
int def=1;
//用于记录当前节点的父节点的位置
int m=nodes[i].parent;
//如果其父节点存在
while(m!=-1&&nodes[m]!=null){
//向上继续搜索父节点
m=nodes[m].parent;
def++;
}
if(max<def){
max=def;
}
}
//返回最大深度
return max;
}
//返回包含指定值的节点
public int pos(Node node){
for(int i=0;i<treeSize;i++){
//找到指定节点
if(nodes[i]==node){
return i;
}
}
return -1;
}
//测试
public static void main(String[] args) {
TreeParent<String> tp=new TreeParent<String>("root");
TreeParent.Node root=tp.root();
System.out.println(root);
tp.addNode("节点1", root);
System.out.println("此树的深度:"+tp.deep());
tp.addNode("节点2", root);
//获取根节点的所有子节点
List<TreeParent.Node<String>> nodes=tp.children(root);
System.out.println("根节点的第一个子节点:"+nodes.get(0));
//为根节点的第一个子节点新增一个字节点
tp.addNode("节点3", nodes.get(0));
System.out.println("此树的深度"+tp.deep());
}
}