最优二叉搜索树

概述

最优二叉搜索树问题是在给定关键字搜索频率的情况下,构造一棵期望搜索代价最小的BST。与普通BST不同,该问题同时考虑了成功搜索(找到关键字)和失败搜索(搜索伪关键字)的频率,是一个经典的动态规划应用。

定义

最优二叉搜索树(Optimal Binary Search Tree)

输入

  • 个排序关键字
  • 成功搜索概率 (搜索 的概率)
  • 失败搜索概率 (搜索值落在 之间的概率)
  • 满足

输出:一棵包含 作为内部节点、 作为叶子的二叉搜索树,使得期望搜索代价最小。

为包含关键字 的最优BST的期望搜索代价,,则:

核心性质

1. 最优子结构

若最优BST的根为 ),则:

  • 左子树必须是由 构成的最优BST(否则替换后代价更小)
  • 右子树必须是由 构成的最优BST

证明(反证法):若左子树存在代价更小的BST,将其替换后,整棵树的期望搜索代价减小——与最优性矛盾。

2. 子树深度增加的代价

当一棵子树成为另一棵树的子树时,子树中所有节点的深度增加1。因此,子树的期望搜索代价需要加上 (子树中所有节点的概率之和)来补偿深度增加。

这正是递推公式中 的含义。

3. 自底向上算法

OPTIMAL-BST(p, q, n):
    let e[1..n+1, 0..n], w[1..n+1, 0..n], root[1..n, 1..n] be new tables
    for i = 1 to n+1:
        e[i, i-1] = q[i-1]
        w[i, i-1] = q[i-1]
    for l = 1 to n:                    // l 为子树中关键字的个数
        for i = 1 to n - l + 1:
            j = i + l - 1
            e[i,j] = ∞
            w[i,j] = w[i,j-1] + p[j] + q[j]  // 利用前缀和高效计算
            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

4. 构造最优解

CONSTRUCT-OPTIMAL-BST(root):
    // root[i,j] 记录了包含 k_i..k_j 的最优BST的根
    // 递归构造整棵树
    return BUILD-TREE(root, 1, n)

BUILD-TREE(root, i, j):
    if j < i:
        return leaf node d[j]
    r = root[i,j]
    left = BUILD-TREE(root, i, r-1)
    right = BUILD-TREE(root, r+1, j)
    return tree node k_r with left and right children

5. 与普通BST的区别

特征普通BST最优BST
构造依据插入顺序搜索频率
目标支持动态操作最小化期望搜索代价
是否平衡不保证不一定平衡
适用场景动态数据集静态数据集(关键字和频率已知)

最优BST适用于关键字集合和搜索频率已知且不频繁变化的场景,例如编译器的符号表、字典的索引结构等。

复杂度分析

指标
时间复杂度
空间复杂度
子问题数量
每个子问题的选择数

章节扩展

参见