📜  最佳二叉搜索树| DP-24(1)

📅  最后修改于: 2023-12-03 15:10:34.407000             🧑  作者: Mango

最佳二叉搜索树 (Best Binary Search Tree)

最佳二叉搜索树 (BBST) 是指对于给定的一组键值及其概率,构建一棵二叉搜索树,使得搜索键值的期望代价最小。

期望代价的计算公式为: $E(搜素代价) = \sum_{i=1}^{n}(深度_i+1)\times p_i$

其中,$p_i$ 表示键值 i 的概率,$深度_i$ 表示键值 i 在二叉搜索树中的深度。

BBST 的问题可以用动态规划算法解决,时间复杂度为 $O(n^3)$。

动态规划思路

设 $e[i][j]$ 和 $w[i][j]$ 分别表示在键 i 到键 j 的范围内,构建 BBST 的期望搜索代价和概率总和。其中, $e[i][i-1]$ 和 $w[i][i-1]$ 均为 $q_{i-1}$,因为当范围为空时,相当于搜索失败。

当 $j=i$ 时,只有一个键值,对应的二叉搜索树只有一个节点,所以 $e[i][i]=w[i][i]=p_i$。

当 $j>i$ 时,对于所有 $i \le k \le j$ ,依次选择 $k$ 作为根节点,将范围分成 $[i,k-1]$ 和 $[k+1,j]$ 两个子范围。则有:

$e[i][j] = \min_{i \le k \le j}{e[i][k-1]+e[k+1][j]+w[i][j]}$ ,其中 $w[i][j] = \sum_{t=i}^{j}p_t$

当范围 $[i, j]$ 中含有多个键值时,我们只需计算 $e[i][j]$ 和 $w[i][j]$ 一次,毕竟同一个范围构成的 BBST 期望搜索代价相同。

最后, $e[1][n]$ 就是整棵 BBST 的期望搜索代价,$e[1][n]$ 中存储的子问题解可用于构建 BBST。

实现

以下是用 Python 实现 BBST 动态规划算法的代码:

def optimal_bst(p, q, n):
    e = [[0 for _ in range(n+1)] for _ in range(n+1)]
    w = [[0 for _ in range(n+1)] for _ in range(n+1)]
    for i in range(1, n+1):
        e[i][i-1] = q[i-1]
        w[i][i-1] = q[i-1]
    
    for l in range(1, n+1):
        for i in range(1, n-l+2):
            j = i + l - 1
            e[i][j] = float('inf')
            w[i][j] = w[i][j-1] + p[j] + q[j]
            for k in range(i, j+1):
                temp = e[i][k-1] + e[k+1][j] + w[i][j]
                if temp < e[i][j]:
                    e[i][j] = temp
    
    return e[1][n]

该算法的时间复杂度为 $O(n^3)$,空间复杂度为 $O(n^2)$。