树的双亲表示法

来源:互联网 发布:sql union和union all 编辑:程序博客网 时间:2024/04/30 23:47

树的双亲表示法是用一组连续空间(数组)存储树的节点,同时在每个节点中附设一个指示器指示其双亲节点在数组中的位置。

其结构如图:

 

 

 

 

 

 

 

 

 

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));             }}}