#include<iostream>
using namespace std;
double C[20][20]; // 最优二叉树的平均比较次数矩阵
int R[20][20]; // 根结点矩阵
// 最优二叉查找树
double OptimalBST(double p[],int n) // 传入字符的查找概率p[n]
{
// 初始化主对角线和第一条次对角线
for(int i=1;i<=n;i++){ // 行(1~n+1)
C[i][i-1] = 0;
C[i][i] = p[i-1]; // 字符对应的概率p[i-1]
R[i][i] = i;
}
C[n+1][n] = 0; // 主对角线的最后一个元素置0
// 按对角线逐条计算
for(int d=1;d<n;d++){
for(int i=1;i<=n-d;i++){ // 该对角线上元素的横坐标
int j = i+d; // 元素对应的列号
double min = 999;
int mink = i; // 最优情况对应的根结点k
double sum = 0;
// 二叉树T(i,j)中取根结点 k(i ≤k ≤j)
for(int k=i;k<=j;k++){
sum = sum + p[k-1]; // p[k-1]为第i个元素的查找概率,注意数组下标从0开始
if(C[i][k-1]+C[k+1][j]<min){
min = C[i][k-1]+C[k+1][j];
mink = k;
}
}
C[i][j] = min+sum;
R[i][j] = mink;
}
}
return C[1][n]; // 最优平均查找次数
}
int main()
{
char s[4] = {'A','B','C','D'};
double p[4] = {0.1,0.2,0.4,0.3};
cout<<"最优二叉树的平均比较次数:"<<OptimalBST(p,4)<<endl;
cout<<"对应的根结点根结点:"<<s[R[1][4]-1]<<endl;
return 0;
}