当前位置:嗨网首页>书籍在线阅读

59-伪代码详解

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

4.10.4 伪代码详解

(1)构建最优二叉搜索树

采用一维数组p[]、q[]分别记录实结点和虚结点的搜索概率,c[i][j]表示最优二叉搜索树T(i,j)的搜索成本,w[i][j]表示最优二叉搜索树T(i,j)中的所有实结点和虚结点的搜索概率之和,s[i][j]表示最优二叉搜索树T(i,j)的根节点序号。首先初始化,令c[i][i−1]=0.0,w[i][i−1]=q[i−1],其中i= 1,2,3,…,n+1。按照递归式计算元素规模是1的{si}(j=i)的最优二叉搜索树搜索成本c[i][j],并记录最优策略,即树根s[i][j],i=1,2,3,…,n。按照递归式计算元素规模是2的{si,si+1}(j=i+1)的最优二叉搜索树搜索成本c[i][j],并记录最优策略,即树根s[i][j],i=1,2,3,…,n−1。以此类推,直到求出所有元素{s1,…,sn} 的最优二叉搜索树搜索成本c[1][n]和最优策略s[1][n]。

void Optimal_BST()
{
     for(i=1;i<=n+1;i++)
     {
          c[i][i-1]=0.0;
          w[i][i-1]=q[i-1];
     }
     for(int t=1;t<=n;t++)                 //t为关键字的规模
          //从下标为i开始的关键字到下标为j的关键字
          for(i=1;i<=n-t+1;i++)
          {
               j=i+t-1;
               w[i][j]=w[i][j-1]+p[j]+q[j];
               c[i][j]=c[i][i-1]+c[i+1][j];//初始化
               s[i][j]=i;                  //初始化
               for(k=i+1;k<=j;k++) //选取i+1到i之间的某个下标的关键字作为从i到j的根,如果组成的树的期望值当前最小,则k为从i到j的根节点
               {
                    double temp=c[i][k-1]+c[k+1][j];
                if(temp<c[i][j]&&fabs(temp-c[i][j])>1E-6)//C++中浮点数因为精度问题不可以直接比较,fabs(temp-c[i][j])>1E-6表示两者不相等
                    {
                         c[i][j]=temp;
                         s[i][j]=k;        //k即为从下标i到j的根节点
                    }
               }
               c[i][j]+=w[i][j];
          }
}

(2)构造最优解

Construct_Optimal_BST(int i,int j,bool flag)表示构建从结点i到结点j的最优二叉搜索树。首次调用时,flag=0、i=1、j=n,表示首次构建,读取的第一个数值s[1][n]为树根,其他递归调用flag=1。

Construct_Optimal_BST(int i,int j,bool flag):首先读取s[i][j],令k=s[i][j],判断如果k−1<i,表示虚结点ek−1是sk的左子树;否则,递归求解左子树Construct_Optimal_BST(i,k−1,1)。判断如果kj,输出虚结点ek是sk的右孩子;否则,输出s[k+1][j]是sk的右孩子,递归求解右子树Construct_Optimal_BST(k +1,j,1)。

void Construct_Optimal_BST(int i,int j,bool flag)
{
     if(flag==0)
     {
           cout<<"S"<<s[i][j]<<" 是根"<<endl;
           flag=1;
     }
     int k=s[i][j];
     //如果左子树是叶子
     if(k-1<i)
     {
          cout<<"e"<<k-1<<" is the left child of "<<"S"<<k<<endl;
     }
     //如果左子树不是叶子
     else
     {
          cout<<"S"<<s[i][k-1]<<" is the left child of "<<"S"<<k<<endl;
          Construct_Optimal_BST(i,k-1,1);
     }
     //如果右子树是叶子
     if(k>=j)
     {
          cout<<"e"<<j<<" is the right child of "<<"S"<<k<<endl;
     }
     //如果右子树不是叶子
     else
     {
          cout<<"S"<<s[k+1][j]<<" is the right child of "<<"S"<<k<<endl;
          Construct_Optimal_BST(k+1,j,1);
     }
}