动态规划:最优二分检索树

来源:互联网 发布:java高级编程书籍 编辑:程序博客网 时间:2024/06/06 13:17

动态规划:最优二分检索树

1、题目

    设n=4,且(a1,a2,a3,a4)=(do,if,stop,then),设P(1:4)=(3,3,1,1),Q(0:4)=(1,3,2,1,1)(概率值“扩大”了16倍),求最优二分检索树

 

2、方法

        动态规划。主要参考方法链接:http://www.cnblogs.com/stemon/p/3407773.html

主要用到的公式为:


初始时有,W(i,i)=Q(i),C(i,i)=0,R(i,i)=0


3、实现代码

#include <stdio.h>#include <stdlib.h> #define MAX_LEN 256typedef struct BtreeNode{int data;BtreeNode* lchild;BtreeNode* rchild;}BtreeNode,*BtreePtr;BtreePtr OptimalBinarySearchTree(int st,int ed,int (*T)[MAX_LEN],int *num) // 构建最优二分检索树 {if(st >= ed) return NULL;BtreePtr  p;p=(BtreePtr)malloc(sizeof(BtreeNode));p->data=num[T[st][ed]];p->lchild=OptimalBinarySearchTree(st,T[st][ed]-1,T,num);p->rchild=OptimalBinarySearchTree(T[st][ed],ed,T,num);return p;}int main(){int index,tmp;int n,i,j,k,l;int P[MAX_LEN],Q[MAX_LEN];int num[MAX_LEN],W[MAX_LEN][MAX_LEN],C[MAX_LEN][MAX_LEN],T[MAX_LEN][MAX_LEN];    printf("请输入真实节点个数:");while(1==scanf("%d",&n)){if(n > 0){printf("请输入真实节点值:"); for(i=1;i<=n;i++)scanf("%d",num+i);printf("请输入各节点成功的概率P:"); for(i=1;i<=n;i++)scanf("%d",P+i);printf("请输入各节点失败的概率Q:");for(i=0;i<=n;i++)scanf("%d",Q+i);break;}printf("n为无效输入.\n");}//初始化for(i=0;i<=n;i++){W[i][i]=Q[i];C[i][i]=0;}for(l=1;l<=n;l++) // 动态规划算法 {for(i=0;i < n;i++){j=i+l;W[i][j]=W[i][j-1]+P[j]+Q[j];//寻找最小的root index=i+1;tmp=C[i][i]+C[i+1][j];for(k=i+2;k<=j;k++){if(C[i][k-1]+C[k][j] < tmp){tmp=C[i][k-1]+C[k][j];index=k;}}C[i][j]=C[i][index-1]+C[index][j]+W[i][j];T[i][j]=index;}}printf("cost=%d,root=%d\n",C[0][n],T[0][n]);BtreePtr mvbt=OptimalBinarySearchTree(0,n,T,num);return 0;}



4、结果截图


0 0
原创粉丝点击