• 最优二分检索树


      前面给出了二分检索树的定义,下图给出了关于保留字的一个子集的两棵二分检索树。

      为了确定标识符x是否在一棵二分检索树中出现,将x先与根比较,如果X比根中标识符小,则检索在左子树中继续;如果x等于根中标识符,则检索成功地终止;否则检索在右子树中继续下去。上述步骤可以形式化为过程Search。

    Line void Search (BinaryTree T,elemType x,int i) {
    //在二分检索树T上查找x,树的每个结点有三个信息段:LChild,IDent
    //和RChild。如果x不在T中,则置i=0,否则将i置成使得IDent(i)=x
    1 i = T;
    2 while(i!=0) {
    3 if(x=IDent[i] {return IDent[i]};//检索成功
    4 else
    5 if(x<IDent[i] { i=Lchild[i]};//检索左子树
    6 else { i=Rchild[i]}; //检索右子树
    7 };//while
    8 }//Search

    已知一个固定的标识符集合,希望产生一种构造二分检索树的方法。可以预料,同一个标识符集合有不同的二分检索树,而不同的二分检索树有不同的性能特征。

    下面说说不成功检索的含义:为了得到二分检索树的成本函数,在这棵检索树的每一棵空子树的位置上加上一个虚构的结点,即外部结点,它们在图4.2中画成方框。所有其它结点是内部结点。如果一棵二分检索树表示n个标识符,那么正好有n个内部结点和n+1个外部结点。每个内部结点代表一次成功检索可能终止的位置。每个外部结点表示一次不成功检索可能终止的位置。

    二分检索树的预期成本可用公式表示如下:
    ΣP(i)*level(ai) + ΣQ(i)*(level(Ei)-l)
        1≤i≤n 0≤i≤n
    定义标识符集(a1,a2,…,an)的最优二分检索树是一棵使(4.1)式取最小值的二分检索树。

    如果T是最优的,则(4.2)式必定是最小值。进而COST(L)对于包含a1,a2,…,ak-1和E0,El,…,Ek-1的所有二分检索树必定是最小值,同理COST(R)也必定是最小值。
    如果用C(i,j)表示包含ai+1,…,aj和Ei,…,Ej的最优二分检索树的成本,那么要让T是最优的,就必须有:
                  COST(L) = C(0,k-1)和COST(R) = C(k,n)
                  而且应该选择k使得 P(k) + C(0,k-1) + C(k,n) + w(0,k-1) + w(k,n) 取最小值。

    因此,关于C(0,n)有
    C(0,n) = min {c(0,k-1) + C(k,n) + P(k) + w(0,k-1) + w(k,n)}
    0<k≤n
    将(4.3)一般化,对任何C(i,j)则有
    C(i,j) = min {C(i,k-1) + C(k,j) + P(k) + W(i,k-1) + W(k,i)}
    i<k≤j
    = min {C(i,k-1) + C(k,j)+W(i,j)}
    i<k≤j

    用下列步骤解(4.4)式可得C(0,n)。
    首先计算所有使得j-i=1的C(i,j)(注意C(i,i)=0且W(i,i)=Q(i),0≤i≤n);
    接着计算所有使得j-i=2的C(i,j);
    然后计算j-i=3的所有C(i,j),等等。
    如果在这计算期间,记下每棵Tij树的根R(i,j),那么最优二分检索树就可以由
    这些R(i,j)构造出来。
    需要指出的是,R(i,j)是使(4.4)式取最小值的k值。

    下面举个例子:找最小成本二分检索树

    Line void OBST(P,Q,n) {
    //给定几个互异的标识符a1<a2<…<an。已知成功检索的概率P(i),1≤i≤n,
    //不成功检索概率Q(i),1≤i≤n。此算法对标识符ai+1,…,an计算最优二分
    //检索树Tij的成本C(i,j)还计算Tij的根R(i,j),Tij的权W(i,j)。
    float P[n], Q[n], C[n][n], w[n][n];int R[n][n];
    1 for(i=0;i<n;i++) {
    2 (w(i,i),R(i,i),C(i,i)) = (Q(i),0,0); //置初值
    3 (w(i,i+1),R(i,i+1),C(i,i+1)) = (Q(i)+Q(i+1)+P(i+1), i+1, Q(i)+Q(i+1)+P(i+1));
    //含一个结点的最优树
    4 };//for
    5 (w(n,n),R(n,n),C(n,n)) = (Q(n),0,0);
    6 for(m=2;m<=n;m++) { //找有m个结点的最优树
    7 for(i=0;i<=n-m;i++) {
    8 j = i+m;
    9 w(i,j)=W(i,j-1) + P(j) + Q(j);
    10 K = 区间[R(i,j-1),R(i+1,j)]中使{C(i,r-1)+C(r,j)}取最小值的r值;
    //用Knuth的结果解(4.4)式
    11 C(i,j) = w(i,j) + C(i,k-1) + C(k,j);
    12 R(i,j) = k;
    13 };//for
    14 };//for
    15} //OBST
  • 相关阅读:
    ASP.NET WebApi 文档Swagger中度优化
    ASP.NET五步打包下载Zip文件
    JavaScript——HashMap实现
    JS实现集合和ECMA6集合
    JavaScript——双向链表实现
    用JavaScript来实现链表LinkedList
    JavaScript结构三层——思想快速介绍
    浏览器自动刷新——基于Nodejs的Gulp LiveReload与VisualStudio完美结合。
    JavaScript原型OOP——你上车了吗?
    再谈JavaScript闭包及应用
  • 原文地址:https://www.cnblogs.com/lihuidashen/p/3420350.html
Copyright © 2020-2023  润新知