动态规划--最优二叉查找树

  刚刚看到这个题目的时候,赶紧有点难呀~ 但是看了网上别人的两篇博客后,发现当把那些概念和方法弄懂后,实现起来还是非常简单的!

  额。。本来想写点什么的,但是看到别人的都写得那么详细了,那我就免了吧。

  主要参考博客:

  http://www.cnblogs.com/Anker/archive/2013/03/13/2958488.html

  http://www.cnblogs.com/lpshou/archive/2012/04/26/2470914.html

  我的代码实现:

/*    最优二叉查找树    */

#include <stdio.h>

#define N 5
#define MIN 999

void optimum_BST(double weight[N+1][N+1], double statics[N+1][N+1], 
                 int root[N+1][N+1], int n, double p[], double q[])
{    
    /* 构造最优二叉搜索树 */

    int i, j, len ,rt;
    double value;
    
    for (i = 1; i <= n; i++)    // 初始化
    {
        weight[i][i-1] = q[i-1];
        statics[i][i-1] = q[i-1];
    }
    
    for (len = 1; len <= n; len++)        // 控制长度
    {
        for (i = 1; i <= n-len+1; i++)  // 起始点
        {
            j = i + len - 1;            // 终点
            weight[i][j] = MIN;
            statics[i][j] = statics[i][j-1] + p[j] + q[j];    // i到j的概率和
            
            for (rt = i; rt <=j; rt++)        // 从i到j选择一个作为根节点
            {
                value = weight[i][rt-1] + weight[rt+1][j] + statics[i][j];
                if (value < weight[i][j])
                {
                    weight[i][j] = value;
                    root[i][j] = rt;
                }
            }
        }
    }
}

void print_tree(int root[N+1][N+1], int start, int end)
{
    /*    打印出最优二叉搜索树的结构 */

    int rt;

    if (start >= end)    return;
    
    rt = root[start][end];        //根节点
    printf("root:%d.
",rt);
    if (rt-1 >= start)
        printf("left child : %d ",root[start][rt-1]);
    else
        printf("left child is NULL ");

    if (rt+1 <= end)
        printf(" right child : %d 
",root[rt+1][end]);
    else
        printf(" right child is NULL 
");

    
    print_tree(root,start,rt-1);
    print_tree(root,rt+1,end);
    
}

int main()
{
    double p[] = {0,0.15,0.10,0.05,0.10,0.20};
    double q[] = {0.05,0.10,0.05,0.05,0.05,0.10};
    double weight[N+1][N+1];    /* weight[i][j]记录i到j的最小搜索权值 */
    double statics[N+1][N+1];    /* statics[i][j]记录i到j的概率和 */
    int root[N+1][N+1];            /* root[i][j]记录i到j的最优搜索二叉树的根节点 */
    int len =0;

    optimum_BST(weight,statics,root,N,p,q);        
    printf("opimum weight is: %0.2f
",weight[1][N]);
    print_tree(root,1,N);

    return 0;
}

2013/11/7    21:40

  程序截图:

 

原文地址:https://www.cnblogs.com/Jason-Damon/p/3413275.html