【算法导论】动态规划之最优二叉查找树

简介:         如果我们想写一个单词查询的软件的话,我们的目的就是让查询的总时间最短,我们首先想到用之前的二叉查找树。我们可以用红黑树或者其它的平衡二叉树来保证每个单词的搜索时间。

        如果我们想写一个单词查询的软件的话,我们的目的就是让查询的总时间最短,我们首先想到用之前的二叉查找树。我们可以用红黑树或者其它的平衡二叉树来保证每个单词的搜索时间。但是每个单词出现的频率一般不同,因此我们希望把频率较大的单词放在离根比较近的地方,频率较小的放在离叶子较近的地方。而且,我们所要查询的单词词库中没有,这也值得考虑。

              

        由上文可知,ki表示单词,di表示不能查到的情况。由上面的例子可知,一棵最优二叉树不一定是高度最小的树。我们也不一定总把频率最大的放在根部。

        和矩阵链乘法一样,穷举所有的可能行肯定不是一个好的算法。由于具有动态规划的特征,毫无疑问,我们将使用动态规划法。

        对于原序列,我们假设第k个元素(采用遍历的方法)作为根时可以得到最优解,由于是二叉查询树,则前k-1个元素在左子树,剩余元素在右子树。接下来,我们要分别在左、右子树中找到最优二叉树,于是我们可以用相同的方法:假设左、右子树中第m,n个为根时,可以得到最优解,依此类推,就可以求得整体最优解。上面的解法中,可能存在左或者右子树为空的情况:


通过推导,可以递推公式:


其中e表示搜索的代价,q[i]为d[i]的出现频率,w为子树总的概率。

具体程序实现如下:

#include<stdio.h>
#define N 7
void Optimal_Bst(float *p,float *q,int n,float e[][N],int root[][N]);

void main()
{
	float p[]={0,0.15,0.1,0.05,0.1,0.2};//关键字出现的概率
	float q[]={0.05,0.1,0.05,0.05,0.05,0.1};//搜索不到关键字的几种情况的概率
	int n=6;//关键字个数
	float e[N][N]={0};//存储搜索的代价
	int root[N][N]={0};//子树的根,便于重构最优二叉树
	Optimal_Bst(p,q,n,e,root);
	for(int i=1;i<6;i++)
		for(int j=5;j>=i;j--)
			printf("从第%d个元素到第%d个元素的最优二叉查找树的顶点为:%d\n",i,j,root[i][j]);
}

void Optimal_Bst(float *p,float *q,int n,float e[][N],int root[][N])
{
	float w[N][N]={0};
	float t=0;
	for(int i=1;i<=n;i++)//左右子树为空的情况
	{
		e[i][i-1]=q[i-1];
		w[i][i-1]=q[i-1];
	}
	for(int l=1;l<=n;l++)
		for(int i=1;i<=n-l+1;i++)
		{
			int j=0;
			j=i+l-1;
			e[i][j]=10000;//初始化为很大的值,可以随意设置
			w[i][j]=w[i][j-1]+p[j]+q[j];//
			
			for(int r=i;r<=j;r++)//r代表以下标r为根,r在所有的子树节点中遍历
			{
				t=e[i][r-1]+e[r+1][j]+w[i][j];
				if(t<e[i][j])
				{
					e[i][j]=t;
					root[i][j]=r;//得到最优二叉树时的根
					
				}
					
			}
		}
}
上述程序运行后,数组e,w,root的结果如下:


上述程序的运行时间为O(n^3),这和前面的矩阵链乘法是一样的。


原文:http://blog.csdn.net/tengweitw/article/details/16972241

作者:nineheadedbird



目录
相关文章
|
18天前
|
机器学习/深度学习 存储 算法
动态规划算法深度解析:0-1背包问题
0-1背包问题是经典的组合优化问题,目标是在给定物品重量和价值及背包容量限制下,选取物品使得总价值最大化且每个物品仅能被选一次。该问题通常采用动态规划方法解决,通过构建二维状态表dp[i][j]记录前i个物品在容量j时的最大价值,利用状态转移方程避免重复计算子问题,从而高效求解最优解。
231 1
|
5月前
|
存储 机器学习/深度学习 算法
KMP、Trie树 、AC自动机‌ ,三大算法实现 优雅 过滤 netty 敏感词
KMP、Trie树 、AC自动机‌ ,三大算法实现 优雅 过滤 netty 敏感词
KMP、Trie树 、AC自动机‌ ,三大算法实现 优雅 过滤 netty  敏感词
|
5月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
146 17
|
5月前
|
存储 监控 算法
局域网上网记录监控的 C# 基数树算法高效检索方案研究
在企业网络管理与信息安全领域,局域网上网记录监控是维护网络安全、规范网络行为的关键举措。随着企业网络数据量呈指数级增长,如何高效存储和检索上网记录数据成为亟待解决的核心问题。基数树(Trie 树)作为一种独特的数据结构,凭借其在字符串处理方面的卓越性能,为局域网上网记录监控提供了创新的解决方案。本文将深入剖析基数树算法的原理,并通过 C# 语言实现的代码示例,阐述其在局域网上网记录监控场景中的具体应用。
128 7
|
7月前
|
人工智能 算法 语音技术
Video-T1:视频生成实时手术刀!清华腾讯「帧树算法」终结闪烁抖动
清华大学与腾讯联合推出的Video-T1技术,通过测试时扩展(TTS)和Tree-of-Frames方法,显著提升视频生成的连贯性与文本匹配度,为影视制作、游戏开发等领域带来突破性解决方案。
207 4
Video-T1:视频生成实时手术刀!清华腾讯「帧树算法」终结闪烁抖动
|
7月前
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
159 3
 算法系列之数据结构-Huffman树
|
8月前
|
存储 算法 Java
算法系列之动态规划
动态规划(Dynamic Programming,简称DP)是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题,并存储这些子问题的解来避免重复计算,从而提高算法的效率。
268 4
算法系列之动态规划
|
9月前
|
算法 Java C++
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
221 5
|
8月前
|
算法 安全 调度
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
|
8月前
|
机器学习/深度学习 算法 测试技术
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”

热门文章

最新文章