動態規劃之最優二叉搜索樹

/*
 * 最優二叉搜索樹
 */
public class OptimalBST {
	private final int MAX=10000;
	private final int SCALE = 5;			//樹的規模
	private double[][]  e= null;			//e[i][j]表示樹ki..kj的期望代價
	private double[][]  w= null;			//子樹期望代價增加值
	private int[][]  root=null;				//記錄子樹的根
	private double[] p = {0,0.15,0.10,0.05,0.10,0.20};	//k1..k5的概率
	private double[] q = {0.05,0.10,0.05,0.05,0.05,0.10};	//d1..d5的概率

	
	public static void main(String[] args) {
		
		OptimalBST obst = new OptimalBST();
		obst.compute();					//最優二叉搜索樹
		obst.print(1, obst.SCALE, 0);	
	}
	
	public OptimalBST() {
		e = new double[SCALE+2][SCALE+1];
		w = new double[SCALE+2][SCALE+1];
		root = new int[SCALE+2][SCALE+1];
		
	}
	
	//計算得到最優二叉搜索樹期望代價
	private void compute() {
		for(int i=1;i<=SCALE+1;i++) {
			e[i][i-1] = q[i-1];
			w[i][i-1] = q[i-1];
		}
		for(int len=1;len<=SCALE;len++) {
			for(int i=1;i<=SCALE-len+1;i++) {
				int j=i+len-1;
				e[i][j] = MAX;
				w[i][j] = w[i][j-1] + p[j] + q[j];
				for(int r=i;r<=j;r++) {
					double t = e[i][r-1] + e[r+1][j]+w[i][j];
					if(t < e[i][j]) {
						e[i][j] = t;
						root[i][j] = r;
					}
				}
			}
		}	
	}
	
	//打印最優二叉查找樹的結構
	void print(int i,int j,int r)
	{
		int rootChild = root[i][j];			//子樹根節點
		if (rootChild == root[1][SCALE]) {
			//輸出整棵樹的根
			System.out.println("k" + rootChild + "是根");
			print(i,rootChild - 1,rootChild);
			print(rootChild + 1,j,rootChild);
			return;
		}

		if (j < i - 1) {
			return;
		}
		else if (j == i - 1) { //遇到虛擬鍵
			if (j < r) {
				System.out.println("d" + j + "是k" + r + "的左孩子");
			}
			else
				System.out.println("d" + j + "是k" + r + "的右孩子");

			return;
		}
		else {      //遇到內部結點
			if (rootChild < r) {
				System.out.println("k" + j + "是k" + r + "的左孩子");
			}
			else {
				System.out.println("k" + j + "是k" + r + "的右孩子");
			}
		}

		print(i,rootChild - 1,rootChild);
		print(rootChild + 1,j,rootChild);
	}	
}


運行結果與算法導論上一致:

k2是根
k1是k2的左孩子
d0是k1的左孩子
d1是k1的右孩子
k5是k2的右孩子
k4是k5的左孩子
k3是k4的左孩子
d2是k3的左孩子
d3是k3的右孩子
d4是k4的右孩子
d5是k5的右孩子









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章