最优二叉搜索树

个人学习记录贴
这里写图片描述

设集合S为排序的n个元素x1<X2<...<Xn,将这些元素存储在一棵二叉树的节点上,以查找x是否存在这些数中,如果x不在,确定x在那个空隙。
检索方法:
1.初始,x与根元素比较;
2.x<根元素,递归进入左子树;
3.x>根元素,递归进入右字数;
4.x=根元素,算法停止,输出x。
5.x到达叶节点,算法停止,输出x不在数组中。

这里写图片描述

存取概率不等情况

空隙: (-∞, x1), (x1, x2), … , (xn−1, xn), (xn,+∞) ,
x0= -∞, xn+1=∞
给定序列S = <x1, x2, …, xn>,
x 在xi 的概率为bi , x 在(xi , xi+1) 的概率为ai ,
S的存取概率分布如下:
P = <a0, b1, a1, b2, a2, … , bn, an>
实例
S={1,2,3,4,5,6}
P=<0.04,0.1,0.01,0.2,0.05,0.2,0.02,0.1,0.02,0.1,0.07, 0.05,0.04>

实例

S={ 1 2 3 4 5 6}
P = < 0.04, 0.1, 0.01, 0.2, 0.05, 0.2,0.02, 0.1, 0.02, 0.1, 0.07, 0.05,
0.04 >
这里写图片描述
m(T1)=[1*0.1+2*(0.2+0.05)+3*(0.1+0.2+0.1)]
+[3*(0.04+0.01+0.05+0.02+0.02+0.07)+2*0.04]
= 1.8+0.71=2.51
S = { 1, 2, 3, 4, 5, 6 }
P= < 0.04, 0.1, 0.01, 0.2, 0.05, 0.2,0.02, 0.1, 0.02, 0.1, 0.07, 0.05,0.04 >
m(T ) [ 0.1*1+0.2* 2+ 3*0.1+4*(0.2+0.05) + 5*0.1 ]+[1*0.04+ 2*0.01+4*(0.05 + 0.02 + 0.04)+5*(0.02 + 0.07)]=3.25
这里写图片描述

平均比较次数计算

这里写图片描述

小结:
一.二叉检索树的构成。
二.给定概率分布下,一棵二叉检索树的平均检索时间估计。
抛出问题:给定数据集S和相关存取概率分布P,求一棵最优的(即平均比较次数最少的)二分检索树。

如何构造最优二叉搜索树

关键问题:
子问题边界界定
如何将该问题归结为更小的子问题
优化函数的递推方程及初值
计算顺序
是否需要标记函数
时间复杂度

算法设计:子问题划分

S[i,j] = <xi, xi+1, … , xj> 是S 以i 和j 作为边界的子数据集
P[i,j] = <ai-1, bi,ai, [ ,i i, i, bi+1, … , bj, aj>是对应S[i,j]存取概率分布
例: S=<A, B, C, D, E>
P=<0.04, 0.1, 0.02, 0.3, 0.02, 0.1, 0.05, 0.2, 0.06, 0.1, 0.01>
S[2,4]=<B, C, D>
P[2,4]=<0.02, 0.3, 0.02, 0.1, 0.05, 0.2, 0.06>
子问题划分:以xk 作为根,划分成两个子问题:
S[i,k−1], P[i,k−1]
S[k+1,j], P[k+1,j]
例: 以B为根,划分成以下子问题:
S[1,1]=<A>,P[1,1]=<0.04, 0.1, 0.02>
S[3,5]=<C,D,E>, P[3,5]=<0.02, 0.1, 0.05, 0.2, 0.06,0.1,0.01>

递推方程

这里写图片描述

证明

这里写图片描述

计算复杂性估计

这里写图片描述
这里写图片描述

小结

划分子问题,以数据结点为树根
定义优化函数,列出递推方程与边界条件
自底向上计算
设立标记函数记录构成最优二叉搜索树或子树根的位置
时间复杂度估计

代码

<html> 
<head> 
<meta charset="UTF-8"> 
<title>最优二叉搜索树</title> 
<script type="text/javascript"> 
var p ; // 关键字概率 
var q ; //非关键字概率 
var n; 
var textview; 
//获取输入输入信息 
function getInputInfo(){ 
textview=document.getElementById("yy"); 
n = prompt("请输入关键字的个数:"); 

p = new Array(n+1); 
q = new Array(n+1); 
for (var i = 0; i <n; i++) { 
p[i+1] = prompt("请输入"+(i+1)+"个关键字的概率p"+n+"个"); 
} 
for (var j= 0; j <=n; j++) { 
q[j] = prompt("请输入"+(j+1)+"个非关键字的概率p"); 
} 

// optimalBST 

var e=new Array(); 
for(var i=0;i<n+2;i++) 
e[i]=new Array(n+1); 

var w=new Array(); 
for(var i=0;i<n+2;i++) 
w[i]=new Array(n+1); 
var root=new Array(); 
for(var i=0;i<n+1;i++) 
root[i]=new Array(n+1); 
for(var i=1;i<n+2;i++) 
{ 

e[i][i-1]=q[i-1]; 
w[i][i-1]=q[i-1]; 
} 

for(var l=1;l<=n;l++) 
{ 
for(var i=1;i<=n-l+1;i++) 
{ 
var j=i+l-1; 
e[i][j]=Number.MAX_VALUE; 
w[i][j]=parseFloat(w[i][j-1])+parseFloat(p[j])+parseFloat(q[j]); 

for(var r=i;r<=j;r++) 
{ 
var t=parseFloat(e[i][r-1])+parseFloat(e[r+1][j])+parseFloat(w[i][j]); 

if(t<e[i][j]) 
{ 
e[i][j]=t; 
root[i][j]=r; 
} 
} 


} 

} 

constructOptimalBST( root, 1, n); 
} 

function constructOptimalBST( root, i, j) 
{ 

var r=root[i][j]; 

if(i==1&&j==n) 
{ 
// alert("k "+r+"是根"); 
// document.write("k"+r+"是根"); 


textview.value=textview.value+"k"+r+"是根"+"\n"; 
} 
if(r-1<i) 
{ 
textview.value=textview.value+"d"+(r-1)+" 是 k"+r+"的左子树"+"\n"; 
}else 
{ 

textview.value=textview.value+"k"+root[i][r-1]+" 是 k"+r+"的左子树"+"\n"; 
constructOptimalBST(root,i,r-1); 
} 

if(j<parseFloat(r)+1) 
{textview.value=textview.value+"d"+j+" 是 k"+r+"的右子树"+"\n"; 

}else 
{textview.value=textview.value+"k"+root[r+1][j]+" 是 k"+r+"的右子树"+"\n"; 

constructOptimalBST(root,r+1,j); 
} 
} 
</script> 
<style type="text/css"> 

div{ 

margin:4px; 
padding:4px; 


} 
.butt{ 

display: inline-block; 
zoom: 1; /* zoom and *display = ie7 hack for display:inline-block */ 
*display: inline; 
vertical-align: baseline; 
margin: 0 2px; 
outline: none; 
cursor: pointer; 
text-align: center; 
text-decoration: none; 
font: 14px/100% Arial, Helvetica, sans-serif; 
padding: .5em 2em .55em; 
text-shadow: 0 1px 1px rgba(0,0,0,.3); 
-webkit-border-radius: .5em; 
-moz-border-radius: .5em; 
border-radius: .5em; 
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2); 
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2); 
box-shadow: 0 1px 2px rgba(0,0,0,.2); 


} 
.center{ 
position: relative; 
top: 200px; 
font-size:12px; 
color:#8B7355; 

} 

</style> 
</head> 
<body> 

<div> 
<button class="butt" onclick="getInputInfo()">开始</button> 
</div> 
<div> 
<textarea type="text" id="yy" style="width: 500px;height: 300px;"> 
</textarea> 
</div> 
<center class="center"> 
&copy;福建师范大学软件学院算法设计与分析 
</center> 

</body> 
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值