问题描述:
已知二叉树集合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 */
运行界面:

在你为自己未来踏踏实实的努力时,那些你感觉从来不会看到的景色,那些你觉得不会遇到的人,正一步步向你走来。