构造最优二叉查找树的动态规划算法

    首先,我们定义集合中的元素的查找概率是已知的(例如,从历史查找的统计数据中得出),这就很自然的引出了一个最优二叉树的问题。

假设a1,a2,…..an是从小到大排列互不相等的键,p1,p2……..pn是他们的查找概率。C( i ,j )是在最优二叉树中成功查找的最小的平均查找次数,i,j 是整数下标, 1<= i <= j <=n。

废话不多说,直接上代码。

#include <string.h>
#include <stdio.h>
float  p[50]; //存放每个元素查找概率
//计算C(i , j)概率和函数
float sunP(int i , int j){
	int k ;
	float sum =0;
	for (k =i-1; k <= j-1 ; k++ )
	{
		sum+= p[k];
	}
	return sum;
}
//主函数
int main(){
	float  C[60][60] , minval = 100.0; //主表
	int R[60][60]; //根表
	int n , i , j , k , d;
	int  kmin ;
	scanf("%d",&n); //输入元素个数和对应的概率
	for (i = 0; i < n ; i++)
	{
		scanf("%f", &p[i]);
	}
	//初始化主表和根表数组
	memset(C, 0 , sizeof(C));
	memset(R, 0 , sizeof(R));
	for (i= 0; i <=n; i++)
	{
		if (i != n)
		{
			C[i][i+1] = p[i];
			R[i][i+1] = i+1;
		}
	}
 
	//对角线计数
	for (d = 1; d<n; d++)
	{
		for (i = 1; i <=n-d ; i++)
		{
			j = i+d;
			minval = 100.0;
			for (k = i; k <=j ; k++)
			{
				if((C[i-1][k-1] + C[k][j]) < minval){
					minval = C[i-1][k-1] + C[k][j];
					kmin = k;
				}
			}
			R[i-1][j] = kmin;
			C[i-1][j] = minval + sunP(i , j);
		}
	}
	//输出矩阵
	printf("\n");
	for (i = 0 ; i <=n ; i++ )
	{
		for (j = 0; j <=n ; j++)
		{
			printf("%.1f  ", C[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	for (i = 0 ; i <=n ; i++ )
	{
		for (j = 0; j <=n ; j++)
		{
			printf("%d  ", R[i][j]);
		}
		printf("\n");
	}
 
	return 0;
}

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/u011125106/article/details/53425479
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞