はなたの日記

ギターのコードについて書きます

ALDS1_7_A Rooted Trees

問題
Rooted Trees | Aizu Online Judge

最近は相変わらずjavaをやっております。今回は木の実装です。
ノードというクラスを作り、その配列に情報を詰め込む、という感じです。

import java.util.Scanner;

class Node {
	private int parent;
	private int depth;
	private String type;
	private int childnum;
	private int[] child;
	
	Node(int d,int p){
		depth=d; parent=p; 
	}
	
	void setChildnum(int childnum){
		this.childnum=childnum;
		child=new int[childnum];
	}
	
	int getChildnum(){ return childnum; }
	
	void setChild(int x,int idx){
		child[idx]=x;
	}
	
	int getChild(int idx){ return child[idx]; }
	
	void setType(){
		if(parent==-1)
			type="root";
		else if(childnum==0)
			type="leaf";
		else 
			type="internal node";
	}
	
	int getParent(){ return parent; }
	
	void setParent(int p){ parent=p; }
	
	int getDepth(){ return depth; }
	
	void setDepth(int d){ depth=d; }
	
	String getType(){ setType(); return type; }
	
	void printChild(){
		
		System.out.print("[");
		
		for(int i=0;i<childnum;i++){
			if(i==childnum-1)
				System.out.print(child[i]);
			else 
				System.out.print(child[i] +", ");
		}
		
		System.out.println("]");
		
	}

}

class alds_7_a {
	
	static int getRoot(Node[] a,int n){
		for(int i=0;i<n;i++){
			if(a[i].getParent() == -1)
				return i;
		}
		return 0;
	}
	
	static void setdepth(Node[] a,int root){
		int c=a[root].getChildnum();
		for(int i=0;i<c;i++){
			int t=a[root].getChild(i);
			a[t].setDepth( a[root].getDepth()+1 );
			setdepth(a,t);
		}
		return;
	}
	
	public static void main(String[] args){
		Scanner scan=new Scanner(System.in);
		
		int n=scan.nextInt();
		Node[] a=new Node[n];
		
		for(int i=0;i<n;i++)
			a[i]=new Node(0,-1);
		
		for(int i=0;i<n;i++){
			int x=scan.nextInt(); int y=scan.nextInt();
			a[x].setChildnum(y);
			for(int j=0;j<y;j++){
				int z=scan.nextInt();
				a[x].setChild(z,j);
				a[z].setParent(x);
			}
		}
		
		int root=getRoot(a,n);
		setdepth(a,root);
		
		for(int i=0;i<n;i++){
			System.out.print("node "+i+": parent = "+a[i].getParent()+", "+"depth = "+a[i].getDepth()+", "+a[i].getType()+", ");
			a[i].printChild();
		}
			
		
	}
}

クラスの練習を兼ねて基本的にprivateを付けて、ゲッタセッタを利用しているのですが、まあ面倒くさいですね。
実際のシステム等で使うには良いのかもしれませんが、競技プログラミングとか、こういう問題の場合はprivateなど付けず、C言語の構造体みたいに適当にアクセスする方が良い気がします。

今回各ノードが持つ子供を

void setChildnum(int childnum){
	this.childnum=childnum;
	child=new int[childnum];
}

こんな感じで無駄なく配列を作って、ここに保存しました。こうやって動的に配列を確保できるのは良いですね。

とここまで書いて、C言語でも同じことできるんじゃね?と思いました。
仮にCの構造体で、ノードXに配列を持たせるなら

typedef struct Node {
    int *child;
}
void setChild(Node a[],int x,int num){
    a[x].child=malloc(sizeof(int)*num); /*numは配列の要素数*/
}

こんな感じになるのでしょうか。javaの方がすっきりしてる気はしますが、やってることはあまり変わらないですね。