算法课外思考题1104(证明)


💡Author:信安2002钱泽枢(ShiQuLiZhi)

🚀欢迎访问我的作业合集:https://sxhthreo.github.io/categories/%E4%BD%9C%E4%B8%9A/

一、证明题1

证明堆排序中构建初始堆的时间复杂度为 $O(n)$。

我们知道,我们构建初始堆时,需要进行操作以维护大根堆/小根堆的性质。如在维护小根堆过程中,需要调用以下函数:

void down(int u)
{
    int t = u;			// t为点、左孩子、右孩子三个点中最小的一个点
    if (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2;
    if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
    if (u != t)			// 根节点不是最小的
    {
        // 与最小的点交换
        swap(h[u], h[t]);
        down(t);		// 递归处理
    }
}

该过程中,除了需要递归调用之外,其余比较等操作花费的运行时间均是 $O(1)$ 的,则该操作的时间代价可以用下面的递归式表示:$T(n)\leq T(\frac{2n}{3})+O(1)$,其中 $O(1)$ 代表其余非递归的操作,由于每个节点的子树数量最多为 $\frac{2}{3}n$,且该最大值仅在最底层恰好半满时取到,如下图所示:

image-最底层恰好半满时的二叉树情况

则 $T(\frac{2n}{3})$ 代表子树递归调用的最大值。

简单推导如下:

假设节点的右子树节点个数为 $2^k - 1$ ,那么左子树节点个数为 $2^{k+1} - 1$,总节点个数为 $2^k + 2^{k+1} -1$,左子树占总数的比例为 $\frac{2^{k+1} - 1}{2^k + 2^{k+1} -1}$。

当$k\rightarrow ∞$时,这个比例为 $ \frac23$。

因此可用 $T(n)\leq T(\frac{2n}{3})+O(1)$ 递归式刻画维护小根堆操作的运行时间。根据迭代法可知,运行时间 $T(n)=O(lgn)$,即高为 $h$ 的堆维护小根堆操作的运行时间为 $O(h)$。

又有高度为 $h$ 的堆最多包含结点数 $\lceil n/2^{h+1}\rceil$,则建堆的总代价为 $\sum_{\mathrm{h}=0}^{\lfloor\operatorname{lgn}\rfloor}\left\lceil\frac{\mathrm{n}}{2^{\mathrm{h}+1}}\right\rceil \mathrm{O}(\mathrm{h})=\mathrm{O}\left(\mathrm{n} \sum_{\mathrm{h}=0}^{\lfloor\operatorname{lgn}\rfloor} \frac{\mathrm{h}}{2^{\mathrm{h}}}\right)$

又根据公式 $\sum_{\mathrm{k}=0}^{\infty} \mathrm{kx}^{\mathrm{k}}=\frac{\mathrm{x}}{(1-\mathrm{x})^{2}}$,有 $\sum_{\mathrm{h}=0}^{\infty} \frac{\mathrm{h}}{2^{\mathrm{h}}}=2$,因此有建堆的总代价:

$\mathrm{O}\left(\mathrm{n} \sum_{\mathrm{h}=0}^{\lfloor\operatorname{lgn}\rfloor} \frac{\mathrm{h}}{2^{\mathrm{h}}}\right)=\mathrm{O}\left(\mathrm{n} \sum_{\mathrm{h}=0}^{\infty} \frac{\mathrm{h}}{2^{\mathrm{h}}}\right)=\mathrm{O}(\mathrm{n})$

故堆排序中构建初始堆的时间复杂度为 $O(n)$。

二、证明题2

证明图 $G$ 中顶点 $v_i$ 到顶点 $v_j$ 之间长度为 $k$ 的路径数量等于 $A^k$ 的第 $(i,j)$ 个元素,其中 $A$ 是图 $G$ 的邻接矩阵。

我们采用数学归纳法证明:

当 $k=1$ 时,若 $a_{ij}=1$,说明存在一条边 $<v_i,v_j>$ ,也即从 $v_i$ 到 $v_j$ 存在一条长度为 $1$ 的路径。

假设当 $k=m$ 时有图 $G$ 中顶点 $v_i$ 到顶点 $v_j$ 之间长度为 $k$ 的路径数量等于 $A^k$ 的第 $(i,j)$ 个元素,则当 $k = m+1$ 时:

由 $A^{(m+1)} =A^{(m)}*A$,故 $a_{ij}^{(m+1)}=\sum_{k=1}^n a_{ik}^{(m)}a_{kj}$

  1. 若 $a_{ik}^{(m)}$ 和 $a_{kj}$ 不都为 $1$,则有$a_{ik}^{(m)} = 0$或 $a_{kj}=0$,即不同时存在从 $v_i$ 到 $v_k$ 长度为 $m$ 的路径和从 $v_k$ 到 $v_j$ 的边,则不存在从 $v_i$ 到 $v_j$ 长度为 $m+1$ 的路径;
  2. 若 $a_{ik}^{(m)}$ 和 $a_{kj}$ 都等于 $1$,则有$a_{ik}^{(m)}*a_{kj}=1$,即存在从 $v_i$ 到 $v_k$ 长度为 $m$ 的路径和从 $v_k$ 到 $v_j$ 的边,则存在一条从 $v_i$ 到 $v_j$ 长度为 $m+1$ 的路径;
  3. 若$a_{kj}$ 等于 $1$ 且 $a_{ik}^{(m)}$ 大于 $1$,则有$a_{ik}^{(m)}*a_{kj}=a_{ik}^{(m)}$,即存在 $a_{ik}^{(m)}$ 条从 $v_i$ 到 $v_k$ 长度为 $m$ 的路径和从 $v_k$ 到 $v_j$ 的边,则存在 $a_{ik}^{(m)}$ 条从 $v_i$ 到 $v_j$ 长度为 $m+1$ 的路径。

综上,对一切 $k$,$A^{(n)}$ 的元素 $a_{ij}^{(n)}$ 表示顶点 $v_i$ 到顶点 $v_j$ 之间长度为 $k$ 的不同路径总数。特别地,我们还可得到,对角线上的元素 $a_{ii}^{(n)}$ 表示经过 $v_i$ 的长度为 $n$ 的不同回路条数。

命题得证。


文章作者: ShiQuLiZhi
版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ShiQuLiZhi !
评论
  目录