最优二叉搜索树问题是对于有序集S及其存取概率或权值(q0,p1,q1,p2,q2,p3,q3),在所有表示有序集S的二叉搜索树中找出一颗具有最小平均路长的二叉搜索树。
解决方法:
使用动态规划方法自底向上逐步构造最优二叉搜索树。
动态规划的两个重要要素是:
1、最优子结构。2、重叠子问题。
1)所谓最优化子结构是说若问题的一个最优解中包含了子问题的最优解,则该问题具有最优子结构。
2)重叠子问题,是指在递归解决方案中,若产生了大量的相同子问题,那么相同的子问题就会被重复计算很多次,这样算法的效率损耗就很大。
问题中,q0,q1,q2,q3为外部节点,即搜索不成功的权值或概率,p1,p2,p3为内部节点,即搜索成功的权值或概率,T[i][j]为一颗从i到j的子树,w[i][j]来存放累计权值,c[i][j]为一颗树的代价,r[i][j]存放一棵树的根。
<1>、算法思路:
(1)、构造只有一个内部节点的最优二叉搜索树:
c[i-1][j]=w[i-1][i]
r[i-1][i]=i
(2)、构造具有m(m>=2)个内部节点的最优二查搜索树:
c[i][j]=w[i][j]+min{c[i][k-1]+c[k][j]},i
r[i][j]=k,i
<2>、算法代码:
#include
using namespace std;
const int n = 3;
int r[n+1][n+1];//存放各最优二叉树搜索树的根
int c[n+1][n+1];//最优二查搜索树的代价(最小平均路长)
int w[n+1][n+1];//存放内部节点外部节点的累计权值
void OBST(int *p,int *q,int n);
void printOBST(int r[n+1][n+1],int i,int j,int n,int f,char ch);
int main()
{
int p[]={0,5,10,50};//内部节点的权值
int q[]={15,10,5,5};//外部节点的权值
cout<<"内部节点的权值为:"<0)
{
if(f==0)
{
cout<<"T("<=i && t<=n)
{
printOBST(r,i,t,n,k,'L');//递归输出左子树的根节点
}
int m=k+1;
if(t<=j)
{
printOBST(r,m-1,j,n,k,'R');//递归输出右子树的根节点
}
}
}