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