• 最优二叉查找树


    问题描述:对于给定的一组改路,构造一个期望搜索代价最小的二叉查找树。
    《算法导论》第二版213页。

    源程序:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    #define KEY_NUMBER 5
    #define INFINITY 1000
    
    //期望搜索代价,只使用1<=i<=n+1,0<=j<=n的表项
    // 其中expected_cost[i,i-1]表示i为根的搜索树的期望搜索代价,该搜索树只包含虚拟键d[i-1]
    float expected_cost[KEY_NUMBER + 2][KEY_NUMBER + 2];
    //只使用1<=i<=j<=n的表项
    int root[KEY_NUMBER + 1][KEY_NUMBER + 1];
    //概率和数组
    float w[KEY_NUMBER + 2][KEY_NUMBER + 2];
    
    /*
     *先根遍历最优二叉查找树
     * start: 待遍历的子树的起始关键字
     * end:待遍历的子树的结束关键字
     * mid:待遍历的子树的树根对应的关键字
     * leaf_index:下一个访问的虚拟键下标
     */
    void ConstructRecursively(int start,int end,int mid,int& leaf_index)
    {
        if(start == mid)
        {
            cout << "d[" << leaf_index << "]是k[" << mid << "]左孩子" << endl;
            leaf_index ++;
            if(mid == end)
            {
                cout << "d[" << leaf_index << "]是k[" << mid << "]右孩子" << endl;
                leaf_index ++;
            }
            else
            {
                int right_child = root[mid + 1][end];
                cout << "k[" << right_child << "]是k[" << mid << "]右孩子" << endl;
                ConstructRecursively(mid + 1,end,right_child,leaf_index);
            }
        }
        else
        {
            int left_child = root[start][mid - 1];
            cout << "k[" << left_child << "]是k[" << mid << "]左孩子" << endl;
            ConstructRecursively(start,mid - 1,left_child,leaf_index);
            if(mid == end)
            {
                cout << "d[" << leaf_index << "]是k[" << mid << "]右孩子" << endl;
                leaf_index ++;
            }
            else
            {
                int right_child = root[mid + 1][end];
                cout << "k[" << right_child << "]是k[" << mid << "]右孩子" << endl;
                ConstructRecursively(mid + 1,end,right_child,leaf_index);
            }
        }
    }
    
    void Construct(int n)
    {
        int root_index = root[1][n];
        cout << "k[" << root_index << "]是根" << endl;
        int leaf_index = 0;
        ConstructRecursively(1,n,root_index,leaf_index);
    }
    
    void OptimalSearch(float *p,float *q,int n)
    {
        //初始化
        for(int i = 1;i <= n + 1;++ i)
        {
            expected_cost[i][i - 1] = q[i - 1];
            w[i][i - 1] = q[i - 1];
        }
        for(int len = 1;len <= n;++ len)
        {
            for(int i = 1;i <= n + 1 - len;++ i)
            {
                int j = i + len - 1;
                expected_cost[i][j] = INFINITY;
                w[i][j] = w[i][j - 1] + q[j] + p[j];
                for(int k = i;k <= j;++ k)
                {
                    double cost = expected_cost[i][k - 1] + expected_cost[k + 1][j] + w[i][j];
                    if(cost < expected_cost[i][j])
                    {
                        expected_cost[i][j] = cost;
                        root[i][j] = k;
                    }
                }
            }
        }
    }
    
    int main()
    {
        float p[6] = {0,0.15,0.10,0.05,0.10,0.20};
        float q[6] = {0.05,0.10,0.05,0.05,0.05,0.10};
        OptimalSearch(p,q,5);
        Construct(5);
        return 0;
    }
    

    看来看去,还是算法导论写得好~~

  • 相关阅读:
    Sass--传多个参数
    Sass--传一个带值的参数
    Sass--传一个不带值的参数
    Sass--调用混合宏
    Sass--混合宏--声明宏
    Sass--伪类嵌套
    Sass-属性嵌套
    Sass--嵌套选择器
    Sass-局部变量和全局变量
    sass--变量
  • 原文地址:https://www.cnblogs.com/rainySue/p/zui-you-er-cha-cha-zhao-shu.html
Copyright © 2020-2023  润新知