问题描述:
给定一个n个不同关键字的已排序的序列
K=<k1,k2,...,kn>
,每个关键字都有一个概率
pi
表示其搜索频率,希望构造一颗搜索代价最小的二叉搜索树。
用于实例的二叉树:
对于一个
n=5
的关键字集合及如下搜索概率,构造二叉树。
i | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
0.15 | 0.10 | 0.05 | 0.10 | 0.20 | ||
qi | 0.05 | 0.10 | 0.05 | 0.05 | 0.05 | 0.10 |
//optimal binary search tree
#include <iostream>
#include <climits>
#include <vector>
using namespace std;
const int N=5;// n=5 is the total nodes;
const double p[N+1]={0,0.15,0.1,0.05,0.1,0.2};//the possibility of k[i]=i being found
const double q[N+1]={0.05,0.1,0.05,0.05,0.05,0.1};//k[i-1]~k[i] possibility
double e[N+2][N+1];//e[i][j]=e[i][r-1]+e[r+1][j]+w[i][j] the cost contain s k[i],..., k[j]
vector< vector<int> > root(N+1);//root[i][j] is the root of tree contains k[i],..., k[j]
double w[N+2][N+1];//avoid overlapping
using namespace std;
void optimal_BST(const double p[],const double q[], int n)
{
int i,j,l,r;
for(i=1;i<=n+1;i++)
{
e[i][i-1]=q[i-1];
w[i][i-1]=q[i-1];
}
for(l=1;l<=n;l++)
{
for(i=1;i<=n-l+1;i++){
j=i+l-1;
e[i][j]=INT_MAX;
w[i][j]=w[i][j-1]+p[j]+q[j];
for(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;
// cout<<i<<" and "<<j<<" root is "<<r<<endl;
}
}
}
}
}
int main(){
for(int i=0;i<=N;i++)
root[i].resize(N+1);
optimal_BST(p,q,N);
cout<<root[1][5]<<'\t'<<e[1][5];
return 0;
}