关闭

最优二叉搜索树动态规划

标签: c++动态规划重叠子问题
1247人阅读 评论(0) 收藏 举报
分类:

问题描述:

最优二叉搜索树问题是对于有序集S及其存取概率或权值(q0,p1,q1,p2,q2,p3,q3),在所有表示有序集S的二叉搜索树中找出一颗具有最小平均路长的二叉搜索树。

解决方法:

使用动态规划方法自底向上逐步构造最优二叉搜索树。

动态规划的两个重要要素是:

1、最优子结构。2、重叠子问题。

1)所谓最优化子结构是说若问题的一个最优解中包含了子问题的最优解,则该问题具有最优子结构。

2)重叠子问题,是指在递归解决方案中,若产生了大量的相同子问题,那么相同的子问题就会被重复计算很多次,这样算法的效率损耗就很大。


问题中,q0,q1,q2,q3为外部节点,即搜索不成功的权值或概率,p1,p2,p3为内部节点,即搜索成功的权值或概率,T[i][j]为一颗从i到j的子树,w[i][j]来存放累计权值,c[i][j]为一颗树的代价,r[i][j]存放一棵树的根。

<1>、算法思路:

(1)、构造只有一个内部节点的最优二叉搜索树:

c[i-1][j]=w[i-1][i]

r[i-1][i]=i

(2)、构造具有m(m>=2)个内部节点的最优二查搜索树:

c[i][j]=w[i][j]+min{c[i][k-1]+c[k][j]},i<k<=j

r[i][j]=k,i<k<=j

<2>、算法代码:

#include<iostream>
using namespace std;

const int n = 3;
int r[n+1][n+1];//存放各最优二叉树搜索树的根
int c[n+1][n+1];//最优二查搜索树的代价(最小平均路长)
int w[n+1][n+1];//存放内部节点外部节点的累计权值

void OBST(int *p,int *q,int n);
void printOBST(int r[n+1][n+1],int i,int j,int n,int f,char ch);

int main()
{
    int p[]={0,5,10,50};//内部节点的权值
    int q[]={15,10,5,5};//外部节点的权值

    cout<<"内部节点的权值为:"<<endl;
    for(int i=1;i<n+1;i++)//输出内部节点的权值
    {
        cout<<"p"<<i<<"="<<p[i]<<endl; 
    }

    cout<<"外部节点的权值为:"<<endl;
    for(int j=0;j<n+1;j++)//输出外部节点的权值
    {
        cout<<"q"<<j<<"="<<q[j]<<endl;
    }

    cout<<endl;
    OBST(p,q,n);
    cout<<"最优二叉搜索树的最小平均路长为:"<<c[0][n]<<endl;

    cout<<"构造的最优二叉搜索树为:"<<endl;//输出最优二叉树搜索树各个子树的根
    printOBST(r,0,n,n,0,'0');

    system("pause");
    return 0;
}

void OBST(int *p,int *q,int n)//自底向上逐步构造w[][],c[][],r[][]
{
    int i,j,k,m,min,u;

    for(i=0;i<n;i++){
        //初始化
        w[i][i]=q[i];
        c[i][i]=r[i][i]=0;

        //构造只有一个内部节点的最优二查搜索树
        w[i][i+1]=w[i][i]+p[i+1]+q[i+1];
        r[i][i+1]=i+1;
        c[i][i+1]=w[i][i+1];
    }

    w[n][n]=q[n];
    r[n][n]=c[n][n]=0;

    for(m=2;m<=n;m++)//构造具有m个内部节点的最优二查搜索树
    {
        for(i=0;i<=n-m;i++){
            //在前一颗树的基础上加以内部节点和一外部节点
            //分别构造具有m,m+1...n个内部节点的最优二查搜索树
            j=i+m;

            w[i][j]=w[i][j-1]+p[j]+q[j];//构造出从i到j的累计权值

            min=c[i+1][j];
            u=i+1;//假定i+1为根

            for(k=i+2;k<=j;k++)//轮流以i+2,i+3...j为根,选代价最小的送min,其根为u
            {
                if(c[i][k-1]+c[k][j]<min)
                {
                    min=c[i][k-1]+c[k][j];
                    u=k;
                }
            }

            c[i][j]=w[i][j]+min;
            r[i][j]=u;
        }
    }
}

void printOBST(int r[n+1][n+1],int i,int j,int n,int f,char ch)
{
    int k=r[i][j];
    if(k>0)
    {
        if(f==0)
        {
            cout<<"T("<<i<<","<<j<<")"<<"的根节点为:"<<k<<endl;
        }
        else
        {
            cout<<ch<<"子树:"<<"T("<<i<<","<<j<<")"<<"的根节点为:"<<k<<endl;
        }

        int t=k-1;
        if(t>=i && t<=n)
        {
            printOBST(r,i,t,n,k,'L');//递归输出左子树的根节点
        }

        int m=k+1;
        if(t<=j)
        {
            printOBST(r,m-1,j,n,k,'R');//递归输出右子树的根节点
        }
    }
}


3
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

动态规划之最优二叉搜索树

我们在之前也讨论过动态规划的例子: 动态规划原理:http://blog.csdn.net/ii1245712564/article/details/45040037 钢条切割问题:http:/...
  • ii1245712564
  • ii1245712564
  • 2015-04-20 15:41
  • 1753

【算法导论】动态规划之“最优二叉搜索树”

详解动态规划之“最优二叉搜索树”
  • cyp331203
  • cyp331203
  • 2015-01-24 16:11
  • 2886

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

前面说过动态规划最典型的就是解决最优化问题的(具有最优子结构的最优化问题),最优二叉查找树就是一个典型的最优化问题。 问题描述: 给定一个n元素的中序序列,它可以有卡特兰数个不同形状的二叉排序树...
  • mengzhejin
  • mengzhejin
  • 2014-07-16 16:25
  • 1960

最优二叉搜索树动态规划算法

最优二叉搜索树动态规划算法题目描述: Java实现:import java.util.Scanner;public class BestBinarySearchTree { public ...
  • whl_program
  • whl_program
  • 2017-06-20 17:45
  • 329

最优二叉搜索树的动态规划算法研究

  • 2014-01-14 15:20
  • 228KB
  • 下载

动态规划之最优二叉搜索树

利用最优二叉搜索树来实现树的搜索代价最小。
  • zhangyifei521
  • zhangyifei521
  • 2016-03-11 15:24
  • 786

构造最优二叉查找树的动态规划算法

首先,我们定义集合中的元素的查找概率是已知的(例如,从历史查找的统计数据中得出),这就很自然的引出了一个最优二叉树的问题。 假设a1,a2,.....an是从小到大排列互不相等的键,p1,p2.......
  • u011125106
  • u011125106
  • 2016-12-01 19:21
  • 413

最优二叉搜索树

问题描述: 给定一个n个不同关键字的已排序的序列K=K=,每个关键字都有一个概率pip_i表示其搜索频率,希望构造一颗搜索代价最小的二叉搜索树。 用于实例的二叉树: 对于一个n=5n=5的关...
  • liuchenjane
  • liuchenjane
  • 2016-11-24 20:03
  • 394

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

1.最优二叉查找树 (1)左孩子 (2)树内关键字k1...kn(中间节点k1 d0,d1,dn ;d0表示小于k1的所有值, dn表示大于kn的所有值,它们对应的搜索概率是 q0,q1...q...
  • u012813201
  • u012813201
  • 2017-03-15 10:17
  • 101

算法导论-第15章-动态规划-15.4 最优二叉搜索树

一、什么是最优二叉查找树 最优二叉查找树: 给定n个互异的关键字组成的序列K=,且关键字有序(k1 图一显示了给定上面的概率分布pi、qi,生成的两个二叉查找树的例子。图二就是在这种...
  • u012243115
  • u012243115
  • 2014-11-10 11:27
  • 584
    个人资料
    • 访问:78097次
    • 积分:1260
    • 等级:
    • 排名:千里之外
    • 原创:43篇
    • 转载:1篇
    • 译文:1篇
    • 评论:20条
    最新评论