树的定义和基本术语:
➢树是由一个集合以及在该集合上定义的一种关系构成的。
➢集合中的元素称为树的结点,所定义的关系称为父子关系。
➢父子关系在树的结点之间建立了一个层次结构。
➢在这种层次结构中有一个结点具有特殊的地位,这个结点称为该树的根结点,或简称为树根。
节点的层次和树的深度:
➢结点的层次( level )从根开始定义,层次数为0的结点是根结点,其子树的根的层次数为1…
➢树中结点的最大层次数称为树的深度( Depth) 或高度。树中结点也有高度,其高度是以该结点为根的树的高度。
节点的度和树的度:
➢结点拥有的子树的数目称为结点的度( Degree )
➢度为0的结点称为叶子( leaf)结点。度不为0的结点称为非终端结点或分支结点。除根之外的分支结点也称为内部结点。
➢性质11.1树中的结点数等于树的边数加1 ,也等于所有结点的度数之和加1。
➢在树中结点总数与边的总数是相当的,基于这一事实,在对涉及树结构的算法复杂性进行分析时,可以用结点的数目作为规模的度量。
路径:
➢在树中k+1个结点通过k条边连接构成的序列{ ( v0,v1 ) ,( v1,v2) …( vk-1,vk) |k≥0} ,称为长度为k的路径( path )
➢树中任意两个结点之间都存在唯一-的路径。 这意味着树既是连通的,同时又不会出现环路。从根结点开始,存在到其他任意结点的一条唯一路径,根到某个结点路径的长度,恰好是该结点的层次数。
有序树、m叉树、森林:
➢如果将树中结点的各子树看成是从左至右是有次序的,则称该树为有序树;若不考虑子树的顺序则称为无序树。对于有序树,我们可以明确的定义每个结点的第一个孩子、 第二个孩子等,直到最后一个孩子。若不特别指明, -般讨论的树都是有序树。
➢树中所有结点最大度数为m的有序树称为m叉树。
➢森林( forest) 是m( m≥0 )棵互不相交的树的集合。对树中
每个结点而言,其子树的集合即为森林。树和森林的概念相近。删去一棵树的根 ,就得到一-个森林;反之,加上一个结点作树根,森林就变为一棵树。
树的节点类如下:
import java.util.LinkedList;
public class TreeNode<E> {
public E key;
public TreeNode<E> parent;
public LinkedList<TreeNode<E>> children;
public TreeNode(E key, TreeNode<E> parent){
this.key = key;
this.parent = parent;
}
public TreeNode(E key){
this.key = key;
}
public String toString(){
return "Node [key=" + key + "]";
}
}
树的接口:
import java.util.LinkedList;
public interface ITree<E> {
int getSize();
TreeNode <E> getRoot();
TreeNode <E> getParent(TreeNode<E> x);
TreeNode<E> getFirstChild(TreeNode<E> x);
TreeNode<E> getNextSibling(TreeNode<E> x);
int getHeight(TreeNode<E> x);
void insertChild(TreeNode<E> x, TreeNode<E> child);
void deleteChild(TreeNode<E> x, int i);
LinkedList<TreeNode <E> > preOrder(TreeNode<E> x);
LinkedList<TreeNode<E> > postOrder(TreeNode<E> x);
LinkedList<TreeNode<E> > levelOrder(TreeNode<E> x);
}
树的实现类:
import java.util.LinkedList;
public class MyTree implements ITree {
private int size = 0;
private TreeNode root;
public MyTree(TreeNode root){
this.root = root;
size++;
}
@Override
public int getSize() {
return size;
}
@Override
public TreeNode getRoot() {
return root;
}
@Override
public TreeNode getParent(TreeNode x) {
return x.parent;
}
@Override
public TreeNode getFirstChild(TreeNode x) {
return (TreeNode) x.children.get(0);
}
@Override
public TreeNode getNextSibling(TreeNode x) {
LinkedList<TreeNode> children = x.parent.children;
int i = children.indexOf(x);
try{
return children.get(i+1);
}catch(Exception e){
return null;
}
}
@Override
public int getHeight(TreeNode x) {
if(x.children == null){
return 0;
}else{
int h = 0;
for(int i=0; i<x.children.size(); i++){
h = Math.max(h, getHeight((TreeNode)x.children.get(i)));
}
return h+1;
}
}
@Override
public void insertChild(TreeNode p, TreeNode child) {
if(p.children == null){
p.children = new LinkedList();
}
p.children.add(child);
child.parent = p;
size++;
}
@Override
public void deleteChild(TreeNode p, int i) {
p.children.remove(i);
size--;
}
@Override
public LinkedList preOrder(TreeNode x) {
return null;
}
@Override
public LinkedList postOrder(TreeNode x) {
return null;
}
@Override
public LinkedList levelOrder(TreeNode x) {
return null;
}
}