您的位置:首页 > 运维架构

最优二叉查找树(optimal BST)

2011-11-26 12:36 330 查看
/**
最优二叉查找树:一棵有n个结点的二叉查找树,已知每个结点的查找概率Pi(且∑Pi=1),要使查找操作的平均比较次数最小。(这里讨论的是成功查找,不讨论不成功的查找)
动态规划:
c[i][j]表示由结点i~j组成的BST成功查找的最小平均查找次数。
r[i][j]表示由结点i~j构成最优二叉查找树时的树根结点。
转换公式:
c[i][j] = Min[i<=k<=j]{c[i,k-1] + c[k+1,j]} + Sum{Pi...Pj};
时间复杂度是O(n^3)
优化:把原来的树根可能是i->j中的任何一个,优化成r[i,j-1] <= r[i,j] <= r[i+1,j]
可以证明优化后的时间复杂度是O(n^2)
**/

const int MAXN = 1000 + 5;

double c[MAXN][MAXN];
int    r[MAXN][MAXN];

double optimalBST(int n, double p[])
{
double sum[MAXN] = {0};
for (int i = 1; i <= n; i++)    // 求前i项和是为了简化后面的计算
sum[i] = sum[i-1] + p[i];
if ( fabs(sum
- 1.0) > 1e-6 ) // 检验∑Pi=1
return -1.0;
for (int i = 1; i <= n; i++)  // initialize
{
c[i][i-1] = 0;
c[i][i] = p[i];
r[i][i] = i;
}
c[n+1]
= 0;
for (int d = 1; d < n; d++)
{
for (int i = 1; i <= n-d; i++)
{
int    j = i + d;
int    root = -1;
double minv = 1e9;

for (int k = r[i][j-1]; k <= r[i+1][j]; k++) // k = i -> j 的优化
{
if (minv > c[i][k-1] + c[k+1][j])
{
minv = c[i][k-1] + c[k+1][j];
root = k;
}
}
r[i][j] = root;
c[i][j] = minv + sum[j] - sum[i-1];
}
}
return c[1]
;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  优化 c