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


     

  • 相关阅读:
    Knockout.js之初印象
    GroupBy之后加ToList和不加ToList有什么区别吗?
    值类型前加ref和out的区别
    引用类型前需要加ref?
    KEPServerEX连接SQLServer数据库操作
    nginx发布网站常用指令
    ASP.NET Core 布局 _Layout.cshtml
    ASP.NET Core-------appsettings.json文件配置与加载
    ASP.NET Core 入门程序
    ASP.NET.Core网站centerOS上部署发布
  • 原文地址:https://www.cnblogs.com/oversea201405/p/3752269.html
Copyright © 2011-2022 走看看