/* 算法导论 15.5-1 打印最优二叉查找树
* 最优二叉查找树
* e[i,j] = q[i-1](j = i-1) e[i,j] = min{e[i,r-1] + r[r+1,j] + w[i,j] | i=<r<=j}
* w[i,j] = w[i,j-1] + p[j] + q[j]
* root[i,j]为k[r]的下标 k[r]是包含关键字的一棵最优二叉树的根
* */
public class OptimalBest {
public static final int N = 5;
public int count = 0;
public static void main(String[] args) {
OptimalBest ob = new OptimalBest();
int[] p = new int[] { 0, 15, 10, 5, 10, 20 };
int[] q = new int[] { 5, 10, 5, 5, 5, 10 };
int[][] e = new int[N + 2][N + 1];
int[][] w = new int[N + 2][N + 1];
int[][] root = new int[N + 1][N + 1];
for (int i = 1; i <= N + 1; i++)
w[i][i - 1] = e[i][i - 1] = q[i - 1];
for (int l = 1; l <= N; l++) {
for (int i = 1; i <= N - l + 1; i++) {
int j = i + l - 1;
e[i][j] = Integer.MAX_VALUE;
w[i][j] = w[i][j - 1] + p[j] + q[j];
for (int r = i; r <= j; r++) {
int 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;
}
}
}
}
ob.construct_optimal_bst(root);
}
private void construct_optimal_bst(int[][] root) {
int r = root[1][N];
System.out.println("k" + r + "是根");
construct_opt_subtree(1, r - 1, r, "左", root);
construct_opt_subtree(r + 1, N, r, "右", root);
}
private void construct_opt_subtree(int i, int j, int r, String dir,
int[][] root) {
if (i <= j) {
int t = root[i][j];
System.out.println("k" + t + "是k" + r + "的" + dir + "孩子");
construct_opt_subtree(i, t - 1, t, "左", root);
construct_opt_subtree(t + 1, j, t, "右", root);
} else {
System.out.println("d" + (count++) + "是k" + r + "的" + dir + "孩子");
}
}
}
输出结果
k2是根
k1是k2的左孩子
d0是k1的左孩子
d1是k1的右孩子
k5是k2的右孩子
k4是k5的左孩子
k3是k4的左孩子
d2是k3的左孩子
d3是k3的右孩子
d4是k4的右孩子
d5是k5的右孩子