树的双亲表示法是用一组连续空间(数组)存储树的节点,同时在每个节点中附设一个指示器指示其双亲节点在数组中的位置。
其结构如图:
package tree;
import java.util.*;
public class PTree<AnyType> {
int max=100;
int n,root;
int a[]=new int[max]; //用于存放孩子结点在数组中的位置
PTNode nodes[]=new PTNode[max];
class PTNode<AnyType>{
AnyType data;
int parent;
public PTNode(AnyType d,int p){
this.data=d;
this.parent=p;
}
}
public PTree(){
n=0;
}
public boolean isEmpty(){ //判断是否为空
return n==0;
}
public PTNode assign(AnyType d,int p){ //给结点赋值
PTNode newNode=new PTNode(d,p);
return newNode;
}
public void insert(AnyType d,int p){ //添加新结点,给定结点位置
nodes[n]=assign(d,p);
n++;
}
public void insert(PTree tree,int p){ //添加子树,给定结点位置
int m=n; //m为tree非根结点双亲位置的增加值
AnyType value=(AnyType)tree.getRoot();
insert(value,p);
for(int i=1;i<tree.n;i++){
AnyType x=(AnyType)tree.getData(i);
insert(x,tree.nodes[i].parent+m); //将tree的非根结点的双亲位置都加m后添加到另一个树中
}
}
public void insert(PTree tree,AnyType d){ //添加子树,给定结点data
int idx=0;
for(int i=0;i<n;i++){
int x=((String)(nodes[i].data)).compareTo((String)d);
if(x==0)
idx=i;
}
int m=n; //m为tree非根结点双亲位置的增加值
AnyType value=(AnyType)tree.getRoot();
insert(value,idx);
for(int i=1;i<tree.n;i++){
AnyType x=(AnyType)tree.getData(i);
insert(x,tree.nodes[i].parent+m); //将tree的非根结点的双亲位置都加m后添加到另一个树中
}
}
public void delete(int p){
if(p>n)
System.out.println("数据不存在");
else if(getChildCount(p)==0){ //叶子
if(p==(n-1)){ //数组的最后一个
nodes[p].data=null;
nodes[p].parent=-2;
}
int k;
for(k=p+1;k<n;k++){
nodes[k-1]=nodes[k]; //令被删除的结点后面的结点向前平移
if(nodes[k].parent>p)
nodes[k].parent--;
}
n--;
}
else{
int dep=getDepth(p);
int num[]=new int[n];
num[0]=p;
int count=1,par=0;
for(int i=0;i<n;i++){
int d=getDepth(i);
par=nodes[i].parent;
while(par!=-1){
if(par==p){
num[count]=i;
count++;
break;
}
par=nodes[par].parent;
d--;
}
}
AnyType a[]=(AnyType[])new Object[count];
for(int i=0;i<count;i++){
a[i]=(AnyType)nodes[num[i]].data;
}/*
System.out.println(a.length);
for(int i=0;i<count;i++){
System.out.println(a[i]);
}*/
int j;
for(j=0;j<n;j++){
for(int x=0;x<a.length;x++){
int y=((String)nodes[j].data).compareTo((String)a[x]);
if(y==0){
int b;
for(b=j+1;b<n;b++) {
nodes[b-1]=nodes[b];
if(nodes[b].parent>j){
nodes[b-1].parent--;
}
}
j--;
n--;
}
}
}
}
}
public AnyType getRoot(){ //返回根结点元素,根结点不一定存在数组中第一个位置
for(int i=0;i<n;i++){
if(nodes[i].parent==-1)
return (AnyType)nodes[i].data;
}
return null;
}
public AnyType getData(int i){ //返回序号为i的结点的数据
if(i>n){
return null;
}
return (AnyType)nodes[i].data;
}
public PTNode getParent(int p){ //返回父母结点,给定该结点位置
int pare=nodes[p].parent;
return nodes[pare];
}
public PTNode getParent(AnyType d){ //返回父母结点,给定该结点data
int p=0;
for(int i=0;i<n;i++){
int x=((String)(nodes[i].data)).compareTo((String)d);
if(x==0)
p=i;
}
int pare=nodes[p].parent;
return nodes[pare];
}
public AnyType getParentData(int p){ //返回父母结点元素
if(p>n){
return null;
}
return (AnyType)getParent(p).data;
}
public int getChildCount(int p){ //返回孩子结点数
int count=0;
for(int i=0;i<n;i++){
if(nodes[i].parent==p){
a[count]=i; //将该结点的孩子结点在数组中的位置存下来
count++;
}
}
return count;
}
public int getChildCount(AnyType d){ //返回孩子结点数,给定结点值
int p=0;
for(int i=0;i<n;i++){
int x=((String)(nodes[i].data)).compareTo((String)d);
if(x==0)
p=i;
}
int count=0;
for(int i=0;i<n;i++){
if(nodes[i].parent==p){
a[count]=i; //将该结点的孩子结点在数组中的位置存下来
count++;
}
}
return count;
}
public PTNode getFirstChild(int p){ //获得第一个孩子结点
int c=getChildCount(p); //得到孩子结点个数
PTNode kong=new PTNode(null,-2);
if(c==0){
return kong;
}
else{
return nodes[a[0]];
}
}
public PTNode getNextChild(int p){
PTNode kong=new PTNode(null,-2);
int c=getChildCount(nodes[p].parent); //执行求该结点的双亲结点的孩子结点的个数的方法,以获得保存其兄弟结点在数组中的位置的数组及孩子个数
int next=0;
for(int i=0;i<c;i++){
if(a[i]==p){
if(i+1<c){ //判断p是否有下一个兄弟结点
next=a[i+1]; //若有,获得p的兄弟结点的位置 ,跳出循环
break;
}
else
return kong; //没有,返回null
}
}
return nodes[next]; //返回兄弟结点
}
public int depth(){
int max=0,height,p=0;//max记录当前的最大高度,p记录双亲结点的位置,height为当前的深度
for(int i=0;i<n;i++){
height=1; //每次循环开始,初始化height
p=nodes[i].parent;
while(p!=-1){ //若当前结点不是根结点,执行此循环
p=nodes[p].parent; //不断沿双亲结点向上走
height++; //没向上一步,高度加一
}
if(height>max) //记录当前最大深度
max=height;
}
return max;
}
public int getDepth(int m){ //获得某一结点所处的层次
if(m>n)
return -2;
int max=0,height,p=0;
for(int i=0;i<n;i++){
height=1; //每次循环开始,初始化height
p=nodes[m].parent;
while(p!=-1){ //若当前结点不是根结点,执行此循环
p=nodes[p].parent; //不断沿双亲结点向上走
height++; //没向上一步,高度加一
}
if(height>max) //记录当前最大深度
max=height;
}
return max;
}
public static void main(String[] args) {
PTree pt=new PTree();
PTree tr=new PTree();
pt.insert("aaa",-1);
pt.insert("bbb",0);
pt.insert("ccc",0);
pt.insert("ddd",1);
pt.insert("eee",2);
pt.insert("fff",2);
pt.insert("ggg",4);
tr.insert("A",-1);tr.insert("B",0);tr.insert("C",0);
pt.insert(tr,"ddd");
for(int i=0;i<10;i++){
System.out.println( pt.getData(i));
}
System.out.println("******************");
System.out.println( pt.n);
System.out.println("******************");
System.out.println( pt.getRoot());
System.out.println("******************");
System.out.println( pt.getParent("fff").data);
System.out.println("******************");
System.out.println( pt.getDepth(9));
System.out.println("******************");
System.out.println(pt.getFirstChild(3).data);
System.out.println("******************");
pt.delete(1);
System.out.println( pt.n);
System.out.println( pt.n);
for(int i=0;i<pt.n;i++){
System.out.println( pt.getData(i));
}
}
}