zoukankan      html  css  js  c++  java
  • 算法笔记-----最优二叉搜索树

      1 //
      2 // Created by alim on 2017/12/23.
      3 //
      4 
      5 #include<iostream>
      6 #include<cmath>   //求绝对值函数需要引入该头文件
      7 using namespace std;
      8 const int M=1000+5;
      9 double c[M][M],w[M][M],p[M],q[M];
     10 int s[M][M];
     11 int n,i,j,k;
     12 void Optimal_BST()
     13 {
     14     for(i=1;i<=n+1;i++)
     15     {
     16         c[i][i-1]=0.0;
     17         w[i][i-1]=q[i-1];
     18     }
     19     for(int t=1;t<=n;t++)//t为关键字的规模
     20         //从下标为i开始的关键字到下标为j的关键字
     21         for(i=1;i<=n-t+1;i++)
     22         {
     23             j=i+t-1;
     24             w[i][j]=w[i][j-1]+p[j]+q[j];
     25             c[i][j]=c[i][i-1]+c[i+1][j];//初始化
     26             s[i][j]=i;//初始化
     27             //选取i+1到j之间的某个下标的关键字作为从i到j的根,如果组成的树的期望值当前最小,则k为从i到j的根节点
     28             for(k=i+1;k<=j;k++)
     29             {
     30                 double temp=c[i][k-1]+c[k+1][j];
     31                 if(temp<c[i][j]&&fabs(temp-c[i][j])>1E-6)//C++中浮点数因为精度问题不可以直接比较
     32                 {
     33                     c[i][j]=temp;
     34                     s[i][j]=k;//k即为从下标i到j的根节点
     35                 }
     36             }
     37             c[i][j]+=w[i][j];
     38         }
     39 }
     40 void Construct_Optimal_BST(int i,int j,bool flag)
     41 {
     42     if(flag==0)
     43     {
     44         cout<<"S"<<s[i][j]<<" 是根"<<endl;
     45         flag=1;
     46     }
     47     int k=s[i][j];
     48     //如果左子树是叶子
     49     if(k-1<i)
     50     {
     51         cout<<"e"<<k-1<<" is the left child of "<<"S"<<k<<endl;
     52     }
     53         //如果左子树不是叶子
     54     else
     55     {
     56         cout<<"S"<<s[i][k-1]<<" is the left child of "<<"S"<<k<<endl;
     57         Construct_Optimal_BST(i,k-1,1);
     58     }
     59     //如果右子树是叶子
     60     if(k>=j)
     61     {
     62         cout<<"e"<<j<<" is the right child of "<<"S"<<k<<endl;
     63     }
     64         //如果右子树不是叶子
     65     else
     66     {
     67         cout<<"S"<<s[k+1][j]<<" is the right child of "<<"S"<<k<<endl;
     68         Construct_Optimal_BST(k+1,j,1);
     69     }
     70 }
     71 int main()
     72 {
     73     cout << "请输入关键字的个数 n:";
     74     cin >> n;
     75     cout<<"请依次输入每个关键字的搜索概率:";
     76     for (i=1; i<=n; i++ )
     77         cin>>p[i];
     78     cout << "请依次输入每个虚结点的搜索概率:";
     79     for (i=0; i<=n; i++)
     80         cin>>q[i];
     81     Optimal_BST();
     82     // /*用于测试
     83     for(i=1; i<=n+1;i++)
     84     {
     85         for (j=1; j<i;j++)
     86             cout <<"	" ;
     87         for(j=i-1;j<=n;j++)
     88             cout << w[i][j]<<"	" ;
     89         cout << endl;
     90     }
     91     for(i=1; i<=n+1;i++)
     92     {
     93         for (j=1; j<i;j++)
     94             cout <<"	" ;
     95         for(j=i-1; j<=n;j++)
     96             cout << c[i][j]<<"	" ;
     97         cout << endl;
     98     }
     99     for(i=1; i<=n;i++)
    100     {
    101         for (j=1; j<i;j++)
    102             cout << "	" ;
    103         for(j=i-1; j<=n;j++)
    104             cout << s[i][j]<<"	" ;
    105         cout << endl;
    106     }
    107     cout << endl;
    108     // */用于测试
    109     cout<<"最小的搜索成本为:"<<c[1][n]<<endl;
    110     cout<<"最优二叉搜索树为:";
    111     Construct_Optimal_BST(1,n,0);
    112     return 0;
    113 }
    114 /**
    115  * 0.04 0.09 0.08 0.02 0.12 0.14
    116  * 0.06 0.08 0.10 0.07 0.05 0.05 0.10
    117  */
    118 /*
    119  * 请输入关键字的个数 n:6
    120 6
    121 请依次输入每个关键字的搜索概率:0.04 0.09 0.08 0.02 0.12 0.14
    122 0.04 0.09 0.08 0.02 0.12 0.14
    123 请依次输入每个虚结点的搜索概率:0.06 0.08 0.10 0.07 0.05 0.05 0.10
    124 0.06 0.08 0.10 0.07 0.05 0.05 0.10
    125 0.06    0.18    0.37    0.52    0.59    0.76    1
    126         0.08    0.27    0.42    0.49    0.66    0.9
    127                 0.1     0.25    0.32    0.49    0.73
    128                         0.07    0.14    0.31    0.55
    129                                 0.05    0.22    0.46
    130                                         0.05    0.29
    131                                                 0.1
    132 0       0.18    0.55    0.95    1.23    1.76    2.52
    133         0       0.27    0.67    0.9     1.38    2.09
    134                 0       0.25    0.46    0.94    1.48
    135                         0       0.14    0.45    0.98
    136                                 0       0.22    0.68
    137                                         0       0.29
    138                                                 0
    139 0       1       2       2       2       3       5
    140         0       2       2       3       3       5
    141                 0       3       3       3       5
    142                         0       4       5       5
    143                                 0       5       6
    144                                         0       6
    145 
    146 最小的搜索成本为:2.52
    147 最优二叉搜索树为:S5 是根
    148 S2 is the left child of S5
    149 S1 is the left child of S2
    150 e0 is the left child of S1
    151 e1 is the right child of S1
    152 S3 is the right child of S2
    153 e2 is the left child of S3
    154 S4 is the right child of S3
    155 e3 is the left child of S4
    156 e4 is the right child of S4
    157 S6 is the right child of S5
    158 e5 is the left child of S6
    159 e6 is the right child of S6
    160 
    161  *
    162  */
  • 相关阅读:
    Python 存储引擎 数据类型 主键
    Python 数据库
    Python 线程池进程池 异步回调 协程 IO模型
    Python GIL锁 死锁 递归锁 event事件 信号量
    Python 进程间通信 线程
    Python 计算机发展史 多道技术 进程 守护进程 孤儿和僵尸进程 互斥锁
    Python 异常及处理 文件上传事例 UDP socketserver模块
    Python socket 粘包问题 报头
    Django基础,Day7
    Django基础,Day6
  • 原文地址:https://www.cnblogs.com/alimjan/p/8116255.html
Copyright © 2011-2022 走看看