最优二叉搜索树

     OBST问题:用二叉树来存数据,不同数据访问频率不一样,怎么样构建这颗二叉树,才可以使得访问代价最小。

     直观的想法是把访问频率最高的放到树的根节点,树越矮越好,但是,很容易举出例子证明这种想法是错的,正确的做法是用动态规划。

     先讲讲用到的变量:

    p[ n ]是n个节点的频率数组,

    e[ i ][ j ] 表示第 i 个节点到第 j 个节点构成的子树的最小搜索代价值,

    w[ i ][ j ]表示第 i 个节点到第 j 个节点的频率和。

     一个事实:如果r是e[ i ][ j ]的根节点(i<=r<=j)那么:

    e[ i ][ j ]=e[ i ][ r-1 ] + e[ r+1 ][ j ] +w[ i ][ j ]  ( i<=j )

  同时定义边界:e[ i ][ j ]=0   ( j=i-1 )

  动态转移方程:

    e[ i ][ j ]=min{ e[ i ][ r-1 ] + e[ r+1 ][ j ] +w[ i ][ j ] }

  用到了3层循环,第一层循环变量是子树的节点个数,第二层循环的变量是子树的起点位置,第三层循环的变量是子树的根节点位置,如此,我们可以得到任意区间OBST的搜索期望是多少。

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define INF 9999;
 5 
 6 void Optimal_BST(double p[],int n){
 7     int i,j,l,r;
 8     int root[n+1][n+1];
 9     double e[n+2][n+2];
10     double w[n+2][n+2];
11     for(i=1;i<=n+1;i++){
12         e[i][i-1]=0;
13         w[i][i-1]=0;
14     }
15     
16     for(l=1;l<=n;l++){
17         for(i=1;   i<=n-l+1;  i++){  // i,j between 1 and n+1,i是左边界,j是右边界 
18             j=i+l-1;
19             e[i][j]=INF;
20             w[i][j]=w[i][j-1]+p[j];     
21             for(r=i;r<=j;r++){
22                 double temp=e[i][r-1]+e[r+1][j]+w[i][j];
23                 if(temp<e[i][j]){
24                     e[i][j]=temp;
25                     root[i][j]=r;
26                 }
27             }
28         }
29     }
30     printf("\n\ne table\n");    
31     for(i=1;i<=n;i++){
32         for(j=1;j<=n;j++){
33             if(i>j)printf("          ");
34             else printf("%f  ",e[i][j]);
35         }
36         printf("\n");
37     }
38     
39     printf("\n\nw table\n");
40     for(i=1;i<=n;i++){
41         for(j=1;j<=n;j++){
42             if(i>j)printf("          ");
43             else printf("%f  ",w[i][j]);
44         }
45         printf("\n");
46     }
47 
48     printf("\n\nroot table\n");
49     for(i=1;i<=n;i++){
50         for(j=1;j<=n;j++){
51             if(i>j)printf("  ");
52             else printf("%d ",root[i][j]);
53         }
54         printf("\n");
55     }
56 }
57 
58 int main(){
59     int n=5;
60     double p[6]={-1,0.25,0.2,0.05,0.2,0.3};
61     Optimal_BST(p,n);
62     return 0;
63 }

 

posted @ 2016-11-27 01:42  侯胜滔  阅读(838)  评论(0编辑  收藏  举报