最优二叉搜索树 (dp)
来源:互联网 发布:中国电信云计算基地 编辑:程序博客网 时间:2024/06/05 01:53
题目:
给n个节点以及每个节点的将要被查询的概率pi,然后把它补充成一个满二叉树,用来补充的节点有n+1个,即di ,每个 di 也有一个查询的概率 qi 。构造最优的二叉搜索树,使总的查询次数最少。
最优二叉搜索树:我的理解是,必须保持原二叉树的中序遍历序列不变的前提下,通过将大概率节点尽量排到接近根的位置,使得总查询次数最少的树。它根哈夫曼编码有相似之处,就是贪心的使大概率节点接近树根,但是它不能够改变原树的中序遍历稳定结构。
思路:
因为最优二字,使用的是dp的思想,把整棵树分成若干子树,其子树也是最优二叉搜索树,满足最优子结构。由这些子树组成得到的一棵树即最终的最优二叉搜索树。详见代码。
代码:
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int MAXN=1000+10;const double INF=1e9+7;int n;double p[MAXN];//每一个节点的查找概率double q[MAXN];//伪关键字的搜索概率double dp[MAXN][MAXN];//dp[i][j] 从节点i到节点j构成的最优查找树的PH值的最小值int root[MAXN][MAXN];//root[i][j] 从节点i到节点j构成的最优查找树的根节点double sum[MAXN][MAXN];//sum[i][j] 区间i到j的的区间概率和void solve(){ for(int len=1; len<=n; len++) { for(int i=1; i<=n-len+1; i++) { int j=i+len-1; dp[i][j]=INF; for(int r=i; r<=j; r++) { double temp; temp=dp[i][r-1]+dp[r+1][j]+sum[i][j]; if(temp<dp[i][j]) { root[i][j]=r; dp[i][j]=temp; } } } }}void init(){ for(int i=1; i<=n; i++) { for(int j=0; j<=n; j++) { if(j==i-1) { sum[i][j]=q[i-1]; dp[i][j]=q[i-1]; } else if(j>=i) { sum[i][j]=sum[i][j-1]+p[j]+q[j]; if(i==j) root[i][j]=i; dp[i][j]=0; } else { sum[i][j]=0; dp[i][j]=0; } } } sum[n+1][n]=dp[n+1][n]=q[n];}void dfs(int l,int r){ if(l>r) { cout<<"{}"; return; } cout<<root[l][r]; int Root=root[l][r]; cout<<"{"; dfs(l,Root-1); cout<<","; dfs(Root+1,r); cout<<"}"; return;}int main(){ cout<<"输入待查找关键字的数量:"<<endl; cin>>n; cout<<"输入"<<n<<"个待查找关键字的搜索频率:"<<endl; for(int i=1; i<=n; i++) cin>>p[i]; cout<<"输入"<<n+1<<"个伪关键字的搜索频率:"<<endl; for(int i=0; i<=n; i++) cin>>q[i]; init(); solve(); cout<<"最小PH值:"<<dp[1][n]<<endl<<"最优查找树构造如下:"<<endl; dfs(1,n); return 0;}
阅读全文
1 0
- 最优二叉搜索树 (dp)
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树
- 最优二叉搜索树(动态规划)
- C++ 最优二叉搜索树
- 最优二叉搜索树问题
- 最优二叉搜索树1
- 最优二叉搜索树2
- 最优二叉搜索树(java)
- 最优二叉搜索树问题
- 弹性和瞬态故障处理库Polly之重试策略
- JAVA多线程与并发学习总结
- CentOS7环境下搭建storm集群
- 搜索引擎选择: Elasticsearch与Solr
- 冒泡排序
- 最优二叉搜索树 (dp)
- Qt多线程学习:创建多线程
- sql 语句实现根据日期字段计算总营业额的查询
- Android8-Oreo奥利奥 SDK下载与各文件解读-1、android_m2repository_r47.zip
- Gem gem,rvm,bundle 区别?
- <C++ Primer_5th>习题_1.11
- inet_ntoa、 inet_aton、inet_addr
- Django框架概念复习
- 如何查看MySQL的版本?