最优二分检索树

https://so.csdn.net/so/search?spm=1000.2115.3001.7498&q=最优二分检索树c%2B%2B&t=&u=&utm_term=最优二分检索树c%2B%2B&utm_medium=distribute.pc_toolbar_associateword.none-task-associate_word-opensearch_query-2-<em>最优二分检索<%2Fem>树c%2B%2B-null-null.179%5Ev5%5Epv&depth_1-utm_source=distribute.pc_toolbar_associateword.none-task-associate_word-opensearch_query-2-<em>最优二分检索<%2Fem>树c%2B%2B-null-null.179%5Ev5%5Epv&request_id=166891597116800186582227&opensearch_request_id=166891597116800186582227文章的实现代码

样例1为:S=<A,B,C,D,E>
P=<0.04,0.1,0.02,0.3,0.02,0.1,0.05,0.2,0.06,0.1,0.01>

样例2为:S=<A,B,C,D>
P=<1,(3),3,(3),2,(1),1,(1),1>  加括号的值是结点的查找概率

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
char txt[]="ABCDEFGHIJKLMN";
double BST(int n,double *p,double *q,double c[20][20],double w[20][20],int r[20][20])
{//p为节点概率从1开始,q为空隙概率从0开始,c为最优检索成本,r为分界记录
	for(int d=0;d<n;d++)
	{
		for(int i=0;i<n-d;i++)
		{
		    int j=i+d+1;
			w[i][j]=q[i];
			for(int t=i+1;t<=j;t++)
				w[i][j]+=q[t];
			for(int t=j;t>j-d-1;t--)
				w[i][j]+=p[t];
			printf("W(%d,%d)=%lf\n",i,j,w[i][j]);
			printf("C(%d,%d)=min{",i,j);
			int R=i;//最优分界
			double MIN=1e9;
			for(int k=i+1;k<=j;k++)
			{
				printf("C(%d,%d)+C(%d,%d)",i,k-1,k,j);
				if(c[i][k-1]+c[k][j]<MIN)
				{
					MIN=c[i][k-1]+c[k][j];
					R=k;
				}	
				if(k!=j)
					printf(",");
			}
			c[i][j]=MIN+w[i][j];
			printf("}+W(%d,%d)=%lf\n",i,j,c[i][j]);
			r[i][j]=R;
			printf("R(%d,%d)=%d\n\n",i,j,R);
		}
	}
	return c[0][n];
}
void printTree(int L,int R,int r[20][20])
{
	printf("%c",txt[r[L][R]-1]);
	//左子树为T(L,r[L][R]-1)  右子树为T(r[L][R],R)
	printf("(");
	if(L!=r[L][R]-1)
		printTree(L,r[L][R]-1,r);
	printf(",");
	if(r[L][R]!=R)
		printTree(r[L][R],R,r);
	printf(")");
}
int main(void)
{
	{
		puts("样例1");
		double q[10]={0.04,0.02,0.02,0.05,0.06,0.01};
		double p[10]={0,0.1,0.3,0.1,0.2,0.1};
		double c[20][20]={0},w[20][20]={0};
		int r[20][20]={0};
		double ans=BST(5,p,q,c,w,r);
		cout<<"最小花费为:"<<ans<<endl;
		printTree(0,5,r);
		cout<<endl;
	}
	{
		puts("样例2");
		double q[10]={1,3,2,1,1};
		double p[10]={0,3,3,1,1};
		double c[20][20]={0},w[20][20]={0};
		int r[20][20]={0};
		double ans=BST(4,p,q,c,w,r);
		cout<<"最小花费为:"<<ans<<endl;
		printTree(0,4,r);
		cout<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值