(p231)15.5-4最优二叉搜索树(n^2和n^3)

对于长度为l的所有子数组的root[i+1][j]-root[i][j-1]+1的和其实就是root[n-l+1][n]-root[1][l]+n-l=o(n),所以两层循环就是n^2,但是并不知道Knuth的结论是怎么来的,希望知道的分享一下^-^

/*attention if max set to 1000 will cause segmentation fault*/
#include<stdio.h>
#include<stdlib.h>
#define max 100
#define inf 1e20
struct node{
	int n;
	struct node *l,*r;
};
float optimal_bst(float p[],float q[],float e[][max+1],int root[][max+1],int n)
{
	int i,j,r,l;
	float w[max+2][max+1];
	for (i=1;i<=n+1;i++)
	{
		e[i][i-1]=q[i-1];
		w[i][i-1]=q[i-1];
	}
	for (l=0;l<=n-1;l++)
		for (i=1;i<=n-l;i++)
		{
			j=i+l;
			w[i][j]=w[i][j-1]+p[j]+q[j];
			e[i][j]=inf;
			for (r=i;r<=j;r++)
				if (e[i][r-1]+e[r+1][j]+w[i][j]<e[i][j])
				{
					e[i][j]=e[i][r-1]+e[r+1][j]+w[i][j];
					root[i][j]=r;
				}
		}
	return e[1][n];
}
float optimal_bst2(float p[],float q[],float e[][max+1],int root[][max+1],int n)
{
	int i,j,r,l;
	float w[max+2][max+1];
	for (i=1;i<=n+1;i++)
	{
		e[i][i-1]=q[i-1];
		w[i][i-1]=q[i-1];
	}
	for (i=1;i<=n;i++)
	{
		root[i][i]=i;
		w[i][i]=w[i][i-1]+p[i]+q[i];
		e[i][i]=e[i][i-1]+e[i+1][i]+w[i][i];
	}
	for (l=1;l<=n-1;l++)
		for (i=1;i<=n-l;i++)
		{
			j=i+l;
			w[i][j]=w[i][j-1]+p[j]+q[j];
			e[i][j]=inf;
			for (r=root[i][j-1];r<=root[i+1][j];r++)
				if (e[i][r-1]+e[r+1][j]+w[i][j]<e[i][j])
				{
					e[i][j]=e[i][r-1]+e[r+1][j]+w[i][j];
					root[i][j]=r;
				}
		}
	return e[1][n];
}
int construct_optimal_bst(int root[][max+1],struct node *troot,int l,int r)
{
	struct node *new;
	int tmp;
	new=(struct node *)malloc(sizeof(struct node));
	if (l>r)
	{
		troot->n=r;
		troot->l=NULL;
		troot->r=NULL;
		return 0;
	}
	tmp=root[l][r];
	troot->n=tmp;
	troot->l=(struct node *)malloc(sizeof(struct node));
	troot->r=(struct node *)malloc(sizeof(struct node));
	construct_optimal_bst(root,troot->l,l,tmp-1);
	construct_optimal_bst(root,troot->r,tmp+1,r);
	return 0;
}
int print(struct node *troot)
{
	if (troot==NULL)
	{
		printf("# ");
		return 0;
	}
	if ((troot->l==NULL)&&(troot->r==NULL))
		printf("d%d ",troot->n);
	else
		printf("k%d ",troot->n);
	print(troot->l);
	print(troot->r);
	return 0;
}
int main(void)
{
	float p[max+1]={0,0.15,0.10,0.05,0.10,0.20};
	float q[max+1]={0.05,0.10,0.05,0.05,0.05,0.10};
	float e[max+2][max+1];
	float ans;
	int root[max+2][max+1],n;//can be reduced to [max+1][max+1]	
	n=5;
	ans=optimal_bst2(p,q,e,root,n);
	printf("%f\n",ans);
	struct node *troot;
	troot=(struct node *)malloc(sizeof(struct node));
	construct_optimal_bst(root,troot,1,n);
	print(troot);
	printf("\n");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值