zoukankan      html  css  js  c++  java
  • 最优二叉搜索树

         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("
    
    e table
    ");    
    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("
    ");
    37     }
    38     
    39     printf("
    
    w table
    ");
    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("
    ");
    46     }
    47 
    48     printf("
    
    root table
    ");
    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("
    ");
    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 }
  • 相关阅读:
    《计算机网络 自顶向下方法》 第3章 运输层 Part1
    Java 字符串截取问题
    Java 字符排序问题
    Linux 下实时查看日志
    Java项目 打war包方法
    Linux 下 安装jdk 1.7
    Linux 下安装jetty服务器
    Linux 系统下安装 rz/sz 命令及使用说明
    Xshell
    Linux 常用命令大全
  • 原文地址:https://www.cnblogs.com/houshengtao/p/6105849.html
Copyright © 2011-2022 走看看