假定有一组英语单词与其法语的翻译,要根据英语单词搜索其法语翻译;有以下两个条件
1. 单词的出现频率不同
2. 有些单词没有对应的法语单词,称为伪单词
在给定单词出现频率的前提下,如果组织一棵二叉搜索树,使得所有搜索操作访问的节点总数最少
问题形式化为
给定一个序列,有n个关键字组成:K =
{k1, k2, ..., kn},对每个关键字有其对应的搜索频率pi
另外有些K中的伪关键字,我们将其分为n+1个集合:D = {d0, d1, ..., dn},其中d0表示小于k1的值,dn表示大于kn的值,di表示在ki和ki+1之间的值,对应的也有搜索频率qi
从而 pi + qj = 1 i = 1, ...n j = 0, ...n
数据结构表示为一棵二叉搜索树,有n个内部结点{k1, k2, ..., kn},n+1个叶子结点{q0, q1, ..., qn}
E[搜索代价] = (depth(ki) + 1) * pi + (depth(dj) + 1) * qj
= 1 + depth(ki) * pi + depth(dj) * qj
i = 1, ...n j = 0, ...n
步骤1:最优二叉搜索树的结构
如果一棵最优二叉搜索树T有一棵包含关键字ki, ..., kj的子树T',则T'必然是包含关键字ki, ..., kj的最优二叉搜索树
步骤2:递归算法
定义e[i, j]为在包含关键字ki, ..., kj的最优二叉搜索树中进行一次搜索的期望代价,最终希望计算出e[1, n]
两种情况
1. j = i - 1,子树只包含伪关键字di-1,从而e[i, j] = qi-1
2. j >= i,需要从ki, ..., kj选择一个根节点kr, 构造左右子树
注意一点:当一棵子树成为一个节点的子树时,期望搜索代价的增加值应该为所有节点概率之和
w(i, j) = pm + qn m = i, ...j n = i-1, ...j
因为深度加一了,从而假设kr为最优二叉树的根节点
e[i, j] = pr + (e[i, r-1] + w(i, r-1)) + (e[r+1, j] + w(r+1, j) = e[i, r-1] + e[r+1, j] + w(i, j)
因此实际上
e[i, j] = min [
e[i, r-1] + e[r+1, j] + w(i, j)] r = i, ...j且i <= j
步骤3:计算
OPTIMAL-BST(p, q, n)
let e[1..n+1, 0..n], w[1..n+1, 0..n], and root[1..n, 1..n] be new tables
// e的第一维从1到n+1,对于只包含伪关键字dn的子树,需要计算并保存e[n+1, n];第二维从0开始,对于只包含伪关键字d0的子树,需要计算并保存e[1, 0]
// root用来保存包含关键字ki, ..., kj的子树的根
// w保存中间结构,避免重复计算
for i=1 to n+1
e[i, i-1] = qi-1
w[i, i-1] = qi-1
for l=1 to n
for i=1 to n-l+1
j = i+l-1
e[i, j] = Inf
w[i, j] = w[i, j-1] + pj + qj
for r = i to j
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
return e and root