最优BST的动态规划算法Java实现

   //输入p: 访问概率数组; 0,1,....n是排好序的Key值
   //输出A=new float[n][n]: 最优时间矩阵
   //输出R=new int[n][n]: 根结点矩阵
   static void optimalBST(float[] p,float[][] A,int[][] R){
	   int n =  p.length;
	   for(int i=0;i<n;i++){		   
		   A[i][i] = p[i];	   
		   R[i][i] = i; //the root is itself
	   }  	   
	    
	   for(int diag=1;diag<n;diag++){
		   for(int i=0;i<n;i++){
			   int j = diag + i;
			   
			   if(j>n-1) break;
			   
			   float min=-1;
			   int root=i;
			   for(int k=i;k<=j;k++){
				   float tmp1 = 0;
				   float tmp2 = 0;
				   if(k-1>=i){
					   tmp1 = A[i][k-1];
				   }
				   if(j>=k+1){
					   tmp2 = A[k+1][j];
				   }
				   float tmp = tmp1 + tmp2;
				   //all min must be greater than 0.
				   if(min<0 || tmp<min){
					   min = tmp;
					   root = k;
				   }				   
			   }
			   R[i][j] = root;
			   A[i][j] = min;
			   for(int m=i;m<=j;m++){
				   A[i][j] += p[m];
			   }
		   }
	   }
	   
   }
本算法只计算平均的BST访问开销A[0][n-1]以及每颗子树的根节点R[i][j],要构建BST,只需从R[0][n-1]递归就可以计算出。时间复杂度O(n^3),与Floyd最短路经算法的复杂度相当。

转载于:https://www.cnblogs.com/ljsspace/archive/2011/06/05/2073342.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态规划算法是一种常见的算法设计思想,它的主要思路是将问题划分为若干个子问题,并且子问题之间存在重叠,通过求解子问题来解决整个问题。通常来说,动态规划算法需要满足三个条件:最优子结构、无后效性和重复子问题。 Python中实现最优二叉查找树的过程如下: 首先,我们需要定义一个节点类Node,用于存储树节点的信息,包括节点值、左右子节点等信息。 其次,我们需要实现一个函数build_optimal_bst,该函数接收一个有序列表keys和对应的概率值probs作为输入,用于构建一棵最优二叉查找树,并返回根节点。 接下来,我们可以实现一个递归函数build_subtree,该函数接收一个有序列表keys、对应的概率值probs、以及当前子树的起始和结束位置作为输入,用于构建当前子树的最优二叉查找树,并返回子树的根节点。 最后,在build_optimal_bst函数中调用build_subtree函数递归构建整棵树,并返回根节点即可。 以下是Python实现最优二叉查找树的代码示例: ``` class Node: def __init__(self, val): self.val = val self.left = None self.right = None def build_optimal_bst(keys, probs): n = len(keys) memo = [ * (n + 1) for _ in range(n + 1)] for i in range(n): memo[i][i] = probs[i] for l in range(2, n + 1): for i in range(n - l + 2): j = i + l - 1 memo[i][j] = float("inf") for k in range(i, j + 1): left_cost = memo[i][k - 1] if k > i else 0 right_cost = memo[k + 1][j] if k < j else 0 curr_cost = left_cost + right_cost + sum(probs[i:j + 1]) if curr_cost < memo[i][j]: memo[i][j] = curr_cost root = Node(keys[k]) root.left = build_subtree(keys, probs, i, k - 1) root.right = build_subtree(keys, probs, k + 1, j) return root def build_subtree(keys, probs, start, end): if start > end: return None elif start == end: return Node(keys[start]) else: min_cost = float("inf") for k in range(start, end + 1): left_cost = memo[start][k - 1] if k > start else 0 right_cost = memo[k + 1][end] if k < end else 0 curr_cost = left_cost + right_cost + sum(probs[start:end + 1]) if curr_cost < min_cost: min_cost = curr_cost root = Node(keys[k]) root.left = build_subtree(keys, probs, start, k - 1) root.right = build_subtree(keys, probs, k + 1, end) return root ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值