问题描述:

  已知二叉树集合p为根结点频率,集合q为叶结点的频率,根据比较权值大小,找出最优二叉搜索树。

备注:

  •   编程语言:c++
  •   编译器:Code::Blocks 16.01
  •   操作系统:windows 10

源代码:

  1 //最优二叉搜索树
  2 
  3 /*测试数据
  4 5
  5 0.15 0.1 0.05 0.1  0.2
  6 0.05 0.1 0.05 0.05 0.05 0.1
  7 */
  8 
  9 #include<iostream>
 10 #include <limits.h>  //极限值头文件,INT_MAX无穷大,INT_MIN无穷小
 11 
 12 using namespace std;
 13 
 14 void OBST(double *p,double *q,int n,double **e,int **r,double **w)
 15 {
 16     for(int i=1;i<=n+1;i++)
 17     {
 18         e[i][i-1]=q[i-1];
 19         w[i][i-1]=q[i-1];
 20     }
 21     for(int l=1;l<=n;l++)
 22     {
 23         for(int i=1;i<=n-l+1;i++)
 24         {
 25             int j=i+l-1;
 26             e[i][j]=INT_MAX;  //INT_MAX(无穷大)
 27             w[i][j]=w[i][j-1]+p[j]+q[j];
 28             for(int k=i;k<=j;k++)
 29             {
 30                 double t=e[i][k-1]+e[k+1][j]+w[i][j];
 31                 if(t<e[i][j])
 32                 {
 33                     e[i][j]=t;
 34                     r[i][j]=k;
 35                 }
 36             }
 37         }
 38     }
 39 }
 40 
 41 int main()
 42 {
 43     int nn;  //根结点个数
 44     double *pp,*qq;  //pp数组:根结点概率  qq数组:叶结点概率
 45     double **ee,**ww;  //ee二维数组:存储树的搜索权值  ww[i][j]=q[i-1]+p[i]+q[i]+...+p[j]+q[j](i,j范围内的所有概率之和)
 46     int **root;  //存放根结点
 47 
 48     cout<<"根结点个数:";
 49     cin>>nn;
 50 
 51     pp = new double[nn+1];
 52     qq = new double[nn+1];
 53     //输入数据
 54     cout<<"根结点概率:"<<endl;
 55     for(int r=1;r<=nn;r++)
 56         cin>>pp[r];
 57     cout<<"叶结点概率:"<<endl;
 58     for(int r=0;r<=nn;r++)
 59         cin>>qq[r];
 60 
 61     //创建动态二维数组
 62     ee = new double*[nn+2];
 63     root = new int*[nn+2];
 64     ww = new double*[nn+2];
 65     for(int i=0;i<=nn+1; i++)
 66     {
 67         ee[i] = new double[nn+1];
 68         root[i] = new int[nn+1];
 69         ww[i] = new double[nn+1];
 70     }
 71 
 72     //赋初值
 73     for(int j=0;j<=nn+1;j++)
 74     {
 75         for(int k=0;k<=nn;k++)
 76         {
 77             ee[j][k]=-1;
 78             root[j][k]=-1;
 79             ww[j][k]=-1;
 80         }
 81     }
 82 
 83     cout<<endl;
 84     OBST(pp,qq,nn,ee,root,ww);//调用函数,根据二维数组root[i][j]画出二叉树
 85 
 86     //输出二维数组
 87     for(int j=0;j<=nn+1;j++)
 88     {
 89         for(int k=0;k<=nn;k++)
 90             cout<<ee[j][k]<<"\t";
 91         cout<<endl;
 92     }
 93     cout<<endl;
 94 
 95     for(int j=0;j<=nn+1;j++)
 96     {
 97         for(int k=0;k<=nn;k++)
 98             cout<<root[j][k]<<"\t";
 99         cout<<endl;
100     }
101     cout<<endl;
102 
103     for(int j=0;j<=nn+1;j++)
104     {
105         for(int k=0;k<=nn;k++)
106             cout<<ww[j][k]<<"\t";
107         cout<<endl;
108     }
109     cout<<endl;
110 
111     //释放空间
112     delete[] pp;
113     delete[] qq;
114 
115     for(int i=0;i<=nn+1;i++)
116     {
117         delete[] ee[i];
118         delete[] root[i];
119         delete[] ww[i];
120     }
121     delete[] ee;
122     delete[] root;
123     delete[] ww;
124 
125     return 0;
126 }
127 
128 /*void OBST(double *a,double *b,int n,double **m,int **s,double **w)
129 {
130     for(int i=0;i <= n;i++)
131     {
132         w[i+1][i] = a[i];
133         m[i+1][i] = 0;
134         s[i+1][i] = 0;
135     }
136 
137     for(int r=0;r < n;r++)
138     {
139         int i,j;
140         for(i=1;i <= n-r;i++)
141         {
142             j = i+r;
143             int i1 = s[i][j-1]>i ? s[i][j-1] : i;
144             int j1 = s[i+1][j]>i ? s[i+1][j] : j;
145 
146             w[i][j] = w[i][j-1] + a[j]+b[j];
147             m[i][j] = m[i][i1-1] + m[i1+1][j];
148             s[i][j] = i1;
149             for(int k=i1+1;k <= j1;k++)
150             {
151                 double t = m[i][k-1] + m[k+1][j];
152                 if(t <= m[i][j])
153                 {
154                     m[i][j] = t;
155                     s[i][j] = k;
156                 }
157             }
158         }
159         m[i][j] += w[i][j];
160     }
161 }
162 
163 void OBST(double *a,double *b,int n,double **m,int **s,double **w)
164 {
165     for(int i=0;i <= n;i++)
166     {
167         w[i+1][i] = a[i];
168         m[i+1][i] = 0;
169     }
170 
171     for(int r=0;r < n;r++)
172     {
173         for(int i=1;i <= n-r;i++)
174         {
175             int j = i+r;
176 
177             w[i][j] = w[i][j-1] + a[j]+b[j];
178             m[i][j] = m[i+1][j];
179             s[i][j] = i;
180             for(int k=i+1;k <= j;k++)
181             {
182                 double t = m[i][k-1] + m[k+1][j];
183                 if(t < m[i][j])
184                 {
185                     m[i][j] = t;
186                     s[i][j] = k;
187                 }
188                 m[i][j] += w[i][j];
189             }
190         }
191     }
192 }
193 
194 */

 

 

 

 
 
运行界面: