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

/*
 * 最优二叉搜索树
 */
public class OptimalBST {
	private final int MAX=10000;
	private final int SCALE = 5;			//树的规模
	private double[][]  e= null;			//e[i][j]表示树ki..kj的期望代价
	private double[][]  w= null;			//子树期望代价增加值
	private int[][]  root=null;				//记录子树的根
	private double[] p = {0,0.15,0.10,0.05,0.10,0.20};	//k1..k5的概率
	private double[] q = {0.05,0.10,0.05,0.05,0.05,0.10};	//d1..d5的概率

	public static void main(String[] args) {

		OptimalBST obst = new OptimalBST();
		obst.compute();					//最优二叉搜索树
		obst.print(1, obst.SCALE, 0);
	}

	public OptimalBST() {
		e = new double[SCALE+2][SCALE+1];
		w = new double[SCALE+2][SCALE+1];
		root = new int[SCALE+2][SCALE+1];

	}

	//计算得到最优二叉搜索树期望代价
	private void compute() {
		for(int i=1;i<=SCALE+1;i++) {
			e[i][i-1] = q[i-1];
			w[i][i-1] = q[i-1];
		}
		for(int len=1;len<=SCALE;len++) {
			for(int i=1;i<=SCALE-len+1;i++) {
				int j=i+len-1;
				e[i][j] = MAX;
				w[i][j] = w[i][j-1] + p[j] + q[j];
				for(int r=i;r<=j;r++) {
					double 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;
					}
				}
			}
		}
	}

	//打印最优二叉查找树的结构
	void print(int i,int j,int r)
	{
		int rootChild = root[i][j];			//子树根节点
		if (rootChild == root[1][SCALE]) {
			//输出整棵树的根
			System.out.println("k" + rootChild + "是根");
			print(i,rootChild - 1,rootChild);
			print(rootChild + 1,j,rootChild);
			return;
		}

		if (j < i - 1) {
			return;
		}
		else if (j == i - 1) { //遇到虚拟键
			if (j < r) {
				System.out.println("d" + j + "是k" + r + "的左孩子");
			}
			else
				System.out.println("d" + j + "是k" + r + "的右孩子");

			return;
		}
		else {      //遇到内部结点
			if (rootChild < r) {
				System.out.println("k" + j + "是k" + r + "的左孩子");
			}
			else {
				System.out.println("k" + j + "是k" + r + "的右孩子");
			}
		}

		print(i,rootChild - 1,rootChild);
		print(rootChild + 1,j,rootChild);
	}
}

运行结果与算法导论上一致:

k2是根
k1是k2的左孩子
d0是k1的左孩子
d1是k1的右孩子
k5是k2的右孩子
k4是k5的左孩子
k3是k4的左孩子
d2是k3的左孩子
d3是k3的右孩子
d4是k4的右孩子
d5是k5的右孩子
时间: 2024-11-03 10:35:40

动态规划之最优二叉搜索树的相关文章

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

之前两篇分别讲了动态规划的"钢管切割"和"矩阵链乘法",感觉到了这一篇,也可以算是收官之作了.其实根据前两篇,到这里,也可以进行一些总结的,我们可以找到一些规律性的东西. 所谓动态规划,其实就是解决递归调用中,可能出现重复计算子问题,从而导致耗费大量时间,去做重复劳动的问题.解决思路就是,将重复做过的子问题的结果,先存起来,等之后再需要用到的时候,直接拿过来用,而不需要再去计算. 但是这里还需要注意一些地方: ①要解决的问题,比如"钢管切割"中的

最优二叉搜索树

OBST问题的解法是动态规划,用到了3层循环, 第一层循环变量是子树的节点个数 l 第二层循环的变量是子树的起点位置i,i即是子树的左边界,j是子树的右边界 第三层循环的变量是子树的根节点位置r 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #define INF 9999; 5 6 void Optimal_BST(double p[],int n){ 7 int i,j,l,r; 8

数据结构第三部分:树与树的表示、二叉树及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树、集合及其运算

参考:浙大数据结构(陈越.何钦铭)课件 1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R 中找出关键字与K 相同的记录).一个自然的问题就是,如何实现有效率的查找? 静态查找:集合中记录是固定的,没有插入和删除操作,只有查找 动态查找:集合中记录是动态变化的,除查找,还可能发生插入和删除 静态查找——方法一:顺序查找(时间复杂度O(n)) int

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

数据结构 ---- 二叉搜索树

一直对于二叉搜索树(又叫二叉排序树,也叫二叉查找树),没有很好的理解,决定花点时间来学习and总结.. 二叉搜索树也是二叉树的一种.(就像堆也就二叉树的一种一样...) 只不过,二叉搜索树也是有其他要求:对于所有的子树,其根节点的值大于左子树上的所有结点的值,而小于右子树上所有结点的值的值.. 对于错误的理解:对于所有的结点,要大于其左结点,小于其右结点..(PS:这种理解是错误的,一定要注意..) 还有一点需要注意的是:我们的大于和小于都应该是严格的. ========== 下面主要针对,其建

【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算

1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R 中找出关键字与K 相同的记录).一个自然的问题就是,如何实现有效率的查找? 静态查找:集合中记录是固定的,没有插入和删除操作,只有查找 动态查找:集合中记录是动态变化的,除查找,还可能发生插入和删除 静态查找--方法一:顺序查找(时间复杂度O(n)) int SequentialSearch(St

二叉搜索树的判断

[TOC] 写在前面的话 初刷leetcode心得,根据题目.定义思考解题方案,第一遍先做出可以运行的答案,第二遍再适当进行速度优化,第三遍看看最优的答案理解其思路. 题目内容 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 二叉搜索树的定义如下: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索树. 1. 解法1 1.1 解题思路 根据二叉排序树的中序遍历性质,可知其中序遍历为递增有序序列,所以可以将遍历结果存在ArrayL

Leetcode 96. 不同的二叉搜索树

题目链接 https://leetcode.com/problems/unique-binary-search-trees/description/ 题目描述 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 题解 首先定义一个函数G[n]:表示1...n构成的二叉搜索树的个数.1..

数据结构之二叉搜索树、AVL自平衡树

前言 最近在帮公司校招~~ 所以来整理一些数据结构方面的知识,这些知识呢,光看一遍理解还是很浅的,看过跟动手做过一遍的同学还是很容易分辨的哟~ 一直觉得数据结构跟算法,就好比金庸小说里的<九阳神功>,学会九阳神功后,有了内功基础,再去学习其他武功,速度就有质的提升 内容大概包含这些,会分多篇文章来整理: 二叉搜索树 平衡二叉树(AVL) 二叉堆 堆排序 四叉树 八叉树 图,深度优先DFS.广度优先BFS 最短路径 二叉树 二叉树,也就是每个节点最多有两个孩子的树.多用于搜索,查找,还有可以用来