您的位置:首页 > 其它

最优二叉搜索树2

2015-10-13 22:22 148 查看
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#define MAX 100

//此函数返回一棵二叉树的最小平均路长
//n为有序集个数
//a[]中存放在二叉树中的叶节点找到x的概率(成功)
//b[]中存放在内节点上找到x的概率(失败)
//s[i][j]存放最优子树T(i,j)根节点的元素
//T(i,j)为有序集{xi..xj}关于存取概率{a[i-1],b[i]...b[j],a[j]}的一棵最优二叉树
//w[i][j]表示查询落在区间(xi-1, xj+1)上的概率
//w[i][j] = a[i-1] + b[i] +…+ b[j] + a[j]
//m[i][j]为子树{xi..xj}最小平均路长,m[1][n]即为整棵二叉树的最小平均路长
double OBST(int n, double a[], double b[], int s[][MAX], double w[][MAX], double m[][MAX])
{
int i, j, r, k;
int i1, j1;
for(i=0; i<=n; i++) //树中只有叶节点
{
w[i+1][i] = a[i];
m[i+1][i] = 0;
}
for(r=0; r<n; r++) //起止下标差,子树规模
{
for(i=1; i<=n-r; i++) //起始下标,当前规模下子树个数
{
j = i+r;  //终止下标
i1 = s[i][j-1]>i?s[i][j-1]:i;  //动态规划加速原理
j1 = s[i+1][j]>i?s[+1][j]:j;
//选i作为根节点
//构造T[i][j] 填写w[i][j],m[i][j],s[i][j]
m[i][j] = m[i][i1-1] + m[i1+1][j]; //动态规划加速原理
w[i][j] = w[i][j-1] + a[j] + b[j];
s[i][j] = i1;
for(k=i1+1; k<=j1; k++) //选取子树中除了i以外的其它节点作为根节点
{  //左子树为节点:i,i+1……k-1,右子树为节点:k+1,k+2,……j
double u = m[i][k-1] + m[k+1][j];
if(u<m[i][j])
{
m[i][j] = u;
s[i][j] = k;
}
}
m[i][j] += w[i][j];
}
}
return m[1]
;
}

int main()
{
double a[] = {0.15, 0.1, 0.05,0.05};
double b[] = {0.00, 0.5, 0.1, 0.05};
int n = 4;
printf("有序集的概率分布为:\n");
for(int i=0; i<4; i++)
{
printf("a%d=%.2f,b%d=%.2f\n", i, a[i], i, b[i]);
}
double m[MAX][MAX], w[MAX][MAX];
int s[MAX][MAX];
double u = OBST(n-1, a, b, s, w, m);
printf("二叉搜索树最小平均路长为: %.2f\n", u);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: