zoukankan      html  css  js  c++  java
  • 树的双亲表示法

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

    其结构如图:

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


     

  • 相关阅读:
    遗传算法(Genetic Algorithm, GA)及MATLAB实现
    CCF CSP 201809-2 买菜
    PAT (Basic Level) Practice (中文)1008 数组元素循环右移问题 (20 分)
    PAT (Basic Level) Practice (中文)1006 换个格式输出整数 (15 分)
    PAT (Basic Level) Practice (中文)1004 成绩排名 (20 分)
    PAT (Basic Level) Practice (中文)1002 写出这个数 (20 分)
    PAT (Advanced Level) Practice 1001 A+B Format (20 分)
    BP神经网络(原理及MATLAB实现)
    问题 1676: 算法2-8~2-11:链表的基本操作
    问题 1744: 畅通工程 (并查集)
  • 原文地址:https://www.cnblogs.com/oversea201405/p/3752269.html
Copyright © 2011-2022 走看看