最优二叉搜索树(动态规划)

 #include <iostream>
#include <type_traits>
#include <vector>
#include <initializer_list>
#include <typeinfo>
enum:int { MAXVALUE=999 };
template<typename T=double, typename Ty=double, typename Type=double>
class BestTree{
 private:
  T** root;//记录给定子树的根节点. 
  Ty** e;//记录子树概率总和. 
  Type** w;//记录子树代价总和.
  std::vector<Ty> p;
  std::vector<Type> q;
  int pLength;
  
  public:
   
   template<typename X=double, typename Y=double>
   BestTree(const std::initializer_list<X>& _p, const std::initializer_list<Y>& _q);//这里的_p指的是每个关键字概率的集合, _q是每个伪关键字集合. 
   
   ~BestTree();
   void OptimalBST();
   void Subtree();
   
};
template<typename T, typename Ty, typename Type>
template<typename X, typename Y>
BestTree<T, Ty, Type>::BestTree(const std::initializer_list<X>& _p, const std::initializer_list<Y>& _q)
                      :p(_p),
                       q(_q)
{
 std::cout<<"test"<<std::endl;
 if(typeid(T)!=typeid(X) || typeid(Ty)!=typeid(Y) || typeid(Type) != typeid(Y)){ //当与我们所需要的类型不一样的时候会抛出异常. 
  throw std::bad_cast();
 }
 
 std::cout<<"test"<<std::endl;
 
 this->pLength=_q.size();
 
 root=new X*[pLength];//创建一个二维数组[pLenght][pLenght]; 
 for(int i=0; i<pLength; ++i){
  root[i]=new X[pLength];
 }
 
 for(int i=0; i<pLength; ++i){
  for(int j=0; j<pLength; ++j){
   this->root[i][j]=T(0);
  }
 }
 
 e=new Y*[pLength+1];//仍然是为了创建一个二维数组。
 w=new Y*[pLength+1];//只有当T,Ty类型与Y相同的时候才会构造成功. 
 for(int i=0; i<pLength+1; ++i){
  e[i]=new Y[pLength];
  w[i]=new Y[pLength];
 }
 
 
  typename std::initializer_list<Y>::iterator iterB=_p.begin();
  //typename std::initializer_list<Y>::iterator iterE=_p.end();
  
  for(int i=0; i<pLength+1; ++i){
   for(int j=0; j<pLength; ++j){
    w[i][j]=T(0);
    e[i][j]=T(0);
   }
  }
    
  for(int m=1; m<pLength+1; ++m){
   e[m][m-1]= *(iterB+m-1);
   w[m][m-1]= *(iterB+m-1);
  }
  
  std::cout<<"success"<<std::endl;
}
template<typename T, typename Ty, typename Type>
void BestTree<T, Ty, Type>::OptimalBST()
{
 std::cout<<"enter"<<std::endl;
 
 for(int l=1; l<this->pLength+1; ++l){ //用来计算1 <= i <= j <= n之间的值. 
  for(int i=1; i<this->pLength-l+1; ++i){
   
   int j=i+l-1; //j的值为1, 2, 3, 4....
   
   this->e[i][j]=MAXVALUE; //假设的最大值.其实就是令e[i][i]=MAXVALUE;
   this->w[i][j]=w[i][j-1]+p[j]+q[j]; //其实是w[i][i-1].
   
    for(int k=i; k<j+1; ++k){ //只有当i=2的时候才开始进入循环. 
     T t=e[i][k-1]+e[k+1][j]+w[i][j]; //这里计算出的是i-j之间的值k是作为分割点的.(按照算法导论来说就是做为子树的根节点.)
     
     if(t < e[i][j]){
      e[i][j]=t;
      root[i][j]=k;
     } 
    }
  }
 }
}
template<typename T, typename Ty, typename Type>
void BestTree<T, Ty, Type>::Subtree()
{
 for(int i=0; i<pLength; ++i){
  
  for(int j=0; j<pLength; ++j){
   std::cout<<this->root[i][j]<<"  ";
  }
  
  std::cout<<std::endl;
 }
}
template<typename T, typename Ty, typename Type>
BestTree<T, Ty, Type>::~BestTree()
{
 if(root != nullptr && w != nullptr && e != nullptr){
  for(int i=0; i<pLength; ++i){
   delete[] root[i];
  }
  delete[] root;
  
  for(int i=0; i<pLength+1; ++i){
   delete[] w[i];
   delete[] e[i];
  }
  
  delete[] w;
  delete[] e;
 }
 
 p.clear();
 q.clear();
}
int main()
{
 BestTree<> myTree( {double(-1), 0.15, 0.1, 0.05, 0.1, 0.2}, {0.05, 0.1, 0.05, 0.05, 0.05, 0.1});
 //注意此处用double(-1),因为模板是不能进行隐式的类型转换的.可以理解为 vector<int> != vector<double>; 
  
 myTree.OptimalBST();
 myTree.Subtree();
 
 return 0;
}

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/544505

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值