算法导论复习

一、数据结构

1、红黑树、序统计树、区间树

1.1 红黑树的性质
  • 每个节点是红色或黑色的
  • 根节点是黑色的
  • 叶节点是黑色的
  • 红色节点的两个孩子节点都是黑色的
  • 从一个节点到后代任意叶节点的简单路径上,黑色节点数相同,即黑高相同
1.2 红黑树的应用 - 顺序统计树、区间树的定义、构造
  • 顺序统计树

    顺序统计树是一种支持快速顺序统计操作的一种数据结构

    其可以在 O ( l g ( n ) ) O(lg(n)) O(lg(n)) 复杂度下去定位一个节点的秩,或找到秩为 x x x 的节点

    它在红黑树的基础上,在每个节点中添加了一个附加信息 s i z e size size,该属性标识以该节点为根的树的节点数

  • 区间树

    区间树是一种对动态集合进行维护的红黑树

1.3 数据结构扩张步骤
  • 选择一种基础数据结构
  • 确定基础数据结构中要维护的附加信息
  • 检查基础数据结构上的基本操作能否维护附加信息
  • 设计一些新的操作
1.4 一些题目
  • 证明:一颗有n个内部节点的红黑树的高度至多为 2 l g ( n + 1 ) 2lg(n+1) 2lg(n+1)

    假设一颗红黑树的高度为 h h h,根据性质4,从根到叶节点的任何一条简单路径上都至少有一半的节点为黑色,因此,根的黑高至少为 h / 2 h/2 h/2,于是有
    n ≥ 2 h / 2 − 1 n \geq 2^{h/2}-1 n2h/21
    从而可以得到 h ≤ 2 l g ( n + 1 ) h \leq 2lg(n+1) h2lg(n+1)

  • 在一棵黑高为 k k k 的红黑树中,内部节点最多可能有多少个?最少可能有多少个?

    最多时,从根节点到任意叶节点的简单路径上,有 k k k 个黑节点,有 k k k 个红节点,此时节点数为 2 2 k − 1 2^{2k}-1 22k1

    最少时,从根节点到任意叶节点的简单路径上,只有 k k k 个黑节点,此时节点数为 2 k − 1 2^k-1 2k1

  • 红黑树新插入节点时,为何不着色为黑色?着色为黑色,就不会破坏性质4啊

    着色为黑色的话,就会破坏性质5,处理起来更加麻烦

2、二项堆

2.1 二项树的定义、性质

对于一颗二项树 B k B_k Bk,它具有以下性质:

  • 2 k 2^k 2k 个节点
  • 树高为 k k k
  • i i i 层上,恰好有 C k i C_k^i Cki 个节点, i ∈ [ 0 ,   k ] i \in [0,\,k] i[0,k]
  • 根节点的度为 k k k,大于其他任意节点;且其 k k k 个孩子节点的度从左到右依次为 k − 1 ,   k − 2 , . . . , 0 k-1,\,k-2,...,0 k1,k2,...,0;同样的,以其孩子节点为根的树也是一颗二项树,不断递归定义下去
  • B k B_k Bk 可由两棵 B k − 1 B_{k-1} Bk1 合并而来
2.2 二项堆的定义

对于一个二项堆 H H H,其遵循以下性质:

  • H H H 中的每一棵二项堆均为小顶堆
  • 对任意一种度数 k k k,其对应的二项树 B k B_k Bk H H H 中最多只出现一次
2.3 根表的性质

在二项堆 H H H 中,维护了一个叫根表的东西,且每个节点的 s i b l i n g sibling sibling 指针指向其兄弟节点,根表是存储二项堆中的所有二项树的根的链表。且,在根表中,每个根的 d e g r e e degree degree 是严格递增的

2.4 二项堆的操作、时间
  • 创建新堆: O ( 1 ) O(1) O(1)
  • 查找最小节点: O ( l g ( n ) ) O(lg(n)) O(lg(n)),对于有n个节点的二项堆,其最多有 ⌊ l g ( n ) ⌋ + 1 \lfloor lg(n) \rfloor + 1 lg(n)+1 个二项树
  • 合并两个二项堆: O ( l g ( n ) ) O(lg(n)) O(lg(n)),遍历根表,相同度数合并
  • 插入节点:创建只含有该节点的新堆,然后合并两个堆, O ( l g ( n ) ) O(lg(n)) O(lg(n))
  • 删除最小节点: O ( l g ( n ) ) O(lg(n)) O(lg(n)),找到最小根,将该节点的孩子节点都放到新堆中,合并两个堆
  • 减小一个节点的值: O ( l g ( n ) ) O(lg(n)) O(lg(n)),最大深度为 ⌊ l g ( n ) ⌋ \lfloor lg(n) \rfloor lg(n)
  • 删除一个节点: O ( l g ( n ) ) O(lg(n)) O(lg(n)),先将节点降为比最小值还要小的值,然后删除最小节点

3、斐波那契堆

3.1 斐波那契堆的定义

一个斐波那契堆是一系列具有最小堆序的有根树的集合。

3.2 根表的性质

在斐波那契堆中,所有的树根都用左右指针链成了一个环形双链表,其中 H . m i n H.min H.min 指向最小根节点, H . n H.n H.n 表示根节点数量。根链表中树的次序可以任意。

3.3 斐波那契堆的势函数

对于给定的斐波那契堆 H H H,用 t ( H ) t(H) t(H) 表示 H H H 中根链表中的树的数量,用 m ( H ) m(H) m(H) 来表示 H H H 中已标记的节点数目,定义势函数如下:
ϕ ( H ) = t ( H ) + 2 m ( H ) \phi(H) = t(H) + 2m(H) ϕ(H)=t(H)+2m(H)

3.4 斐波那契堆的操作、时间
  • 创建一个空斐波那契堆: O ( 1 ) O(1) O(1)

  • 插入一个节点:真实代价 O ( 1 ) O(1) O(1),摊还代价 O ( 1 ) O(1) O(1)

  • 寻找最小节点:真实代价 O ( 1 ) O(1) O(1),摊还代价 O ( 1 ) O(1) O(1)

  • 合并斐波那契堆:真实代价 O ( 1 ) O(1) O(1),摊还代价 O ( 1 ) O(1) O(1)

    连接两个根表,从 H 1 . m i n H_1.min H1.min H 2 . m i n H_2.min H2.min 中选出最小根节点作为 H . m i n H.min H.min,并更新 H . m i n = H 1 . m i n + H 2 . m i n H.min=H_1.min+H_2.min H.min=H1.min+H2.min

    **疑问:**若仅是这样合并,根表中同一种度数的节点会有多个

  • 抽取最小节点:摊还代价 O ( l g ( n ) ) O(lg(n)) O(lg(n))

    首先找到最小节点,若有孩子节点,则将其孩子节点添加到根表中,最后移除最小节点 z z z,此时若 z z z 的右孩子为自己,说明根表中无其他节点了,所以根表置空,否则执行 H . m i n = z . r i g h t H.min=z.right H.min=z.right,并调用合并根链表操作。

    合并根链表操作需要一个辅助空间 A [ 0.. D ( H . n ) A[0..D(H.n) A[0..D(H.n),其中 A [ i ] A[i] A[i]表示当前遇到过的度数 i i i 指向的节点,如果有两个节点相同,则合并之。

    合并根链表时是从 H . m i n H.min H.min 开始遍历根链表的,所以开始之前 H . m i n H.min H.min 是否指向最小节点并不重要

  • 关键字减值:实际代价 O ( c ) O(c) O(c),摊还代价 O ( 1 ) O(1) O(1),其中 c c c 是执行级联剪除函数的次数

    假设要将节点 x x x 的值减小到 k k k,首先要保证新值 k k k 不大于旧值,接着,若新值没有违反最小堆序,那么可以直接结束,否则,需要将节点 x x x 剪除,并向上级联剪除,级联剪除过程如下:

    CASCADING-CUT(H, x):
    	z = x.parent
    	if x.mark = false:
    		x.mark = true
    	else:
    		CUT(x)
    		CASCADING-CUT(H, z)
    

    对于一个节点 x x x,若:

    • 1、在某时刻 x x x 为根节点
    • 2、 x x x 被链接到某节点后变成了孩子节点
    • 3、 x x x 的两个孩子节点被剪除

    那么,若条件1、2发生,并且 x x x 的一个孩子节点被剪除,则 x . m a r k = t r u e x.mark=true x.mark=true,若在 x . m a r k = t r u e x.mark=true x.mark=true时, x x x 又被剪掉了一个孩子节点,那么, x x x 就会被级联剪除掉。

    也就是说,每一次剪除都会产生一个根节点

    对该方法进行势能分析:

    若剪除了节点 x x x,后又进行了 c − 1 c-1 c1次的级联剪除,那么共会产生 c c c棵新树,标记数的变化为: c − 1 c-1 c1次级联剪除会消除 c − 1 c-1 c1个标记,但是最后一次尝试级联时因未标记节点,故会产生一个标记节点,故新的标记数为 m ( H ) − c + 2 m(H)-c+2 m(H)c+2

    势能变化如下:
    t ( H ) + c + 2 ∗ ( m ( H ) − c + 2 ) − [ t ( H ) + 2 ∗ m ( H ) ] = 4 − c t(H) + c + 2 * (m(H)-c+2) - [t(H) + 2 * m(H)] = 4-c t(H)+c+2(m(H)c+2)[t(H)+2m(H)]=4c
    那么根据势能法的摊还分析,最终的摊还代价为:
    O ( c ) + 4 − c = O ( 1 ) O(c) + 4 - c = O(1) O(c)+4c=O(1)

  • 删除一个节点: O ( l g ( n ) ) O(lg(n)) O(lg(n))

    先减值减到最小,再进行抽取最小值节点操作

  • 斐波那契堆的最大度数界为 O ( l g ( n ) ) O(lg(n)) O(lg(n))

3.5 一些题目
  • 若只支持合并堆操作,那么含有n个节点的斐波那契堆中的最大度数为 ⌊ l g ( n ) ⌋ \lfloor lg(n) \rfloor lg(n)

    1. n = 2 k n = 2^k n=2k,则该堆中只有一颗二项树,此时该根节点有最大度数为 D ( n ) = k = ⌊ l g ( n ) ⌋ D(n)=k=\lfloor lg(n) \rfloor D(n)=k=lg(n)
    2. n = 2 k + i n=2^k+i n=2k+i,此时斐波那契堆中出现的节点数最多的二项树有 2 k 2^k 2k个节点,该树根节点度数为 D ( 2 k ) = k = ⌊ l g ( n ) ⌋ D(2^k)=k=\lfloor lg(n) \rfloor D(2k)=k=lg(n)

    综上所述,含有n个节点的斐波那契堆中的最大度数为 ⌊ l g ( n ) ⌋ \lfloor lg(n) \rfloor lg(n)

  • 使用聚合分析来证明 FIB-HEAP-DECREASE-KEY 的 O ( 1 ) O(1) O(1) 摊还时间是每一个操作的平均代价

    假设第 i i i 次调用减值函数会调用 c i c_i ci 次级联切断函数,故 n n n 次调用一共可能调用 ∑ i = 0 n − 1 c i \sum_{i=0}^{n-1}c_i i=0n1ci 次级联切断。

    但是,每一次CUT,都会产生一个根节点,而根节点无法再进行级联切断,故最多只能执行 n n n 次切断,总代价为 O ( n ) O(n) O(n)

    因此,n次调用的平摊代价为 O ( n ) / n = O ( 1 ) O(n)/n=O(1) O(n)/n=O(1)

二、算法设计方法

1、分治法

1.1 基本步骤
  • **分解:**将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小
  • **解决:**递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解
  • **合并:**将子问题的解组合成原问题的解
1.2 适用条件

原问题可被分解为规模更小的相同问题

1.3 相关算法
  • 归并排序
  • 最大子数组问题
  • 矩阵乘法的Strassen算法

2、动态规划

2.1 基本步骤
  • 描述最优解的结构特征
  • 递归地定义一个最优解的值
  • 自底向上计算一个最优解的值——计算最优解
  • 从已知的计算信息中构造一个最优解——构造最优解
2.2 基本要素
  • 最优子结构
  • 重叠子问题
2.3 相关算法
  • 矩阵链乘
  • 钢条切割
  • 最长公共子序列(LCS)
  • 最优二叉搜索树
2.4 如何证明最优子结构性质

利用cut-and-paste技术证明:作为构成原问题最优解的组成部分,每个子问题的解就是它本身的最优解,证明这一点是利用反证法:

假定子问题的解不是其自身的最优解,那么我们可以从原问题的解中”剪切“掉这些非最优解,将最优解”粘贴“进去,进而得到原问题的一个更优解,然而这与最初的解释原问题的最优解的前提假设矛盾。

3 、贪心法

3.1 基本思想
  1. 将最优化问题转化为这样的形式:对其做出一次选择后,只剩下一个子问题需要求解
  2. 证明做出贪心选择后,原问题总是存在最优解,即贪心选择总是安全的
  3. 证明做出贪心选择后,剩余的子问题满足性质:其最优解与贪心选择组合即可得原问题的最优解,这样就得到了最优子结构
3.2 基本要素
  • 最优子结构性质
  • 贪心选择性质
3.3 相关算法
  • 活动选择问题
  • 赫夫曼编码
3.4 理论基础 - 胚的定义及相关概念

矩阵胚又称拟阵,是满足下述条件的序偶 M = ( S ,    Γ ) M=(S,\; \Gamma) M=(S,Γ)

  1. S S S 是一个有限集
  2. Γ \Gamma Γ S S S 子集的一个非空族,并且对于任意 B ∈ Γ B \in \Gamma BΓ,若 A ⊆ B A \subseteq B AB,有 A ∈ Γ A \in \Gamma AΓ。此性质称为遗传性
  3. A ∈ Γ ,    B ∈ Γ A \in \Gamma,\; B \in \Gamma AΓ,BΓ,且 ∣ A ∣ < ∣ B ∣ |A| < |B| A<B,则对于 x ∈ B − A x \in B-A xBA,有 A ∪ { x } ∈ Γ A \cup \{x\} \in \Gamma A{x}Γ。此性质称为交换性
3.5 三种方法的相同及不同点
3.6 贪心选择性质的证明

正常的贪心选择为:选择一个元素,选择的元素为要得到的最优解

非正常的贪心选择为:选择一个元素,剩下的元素为要得到的最优解

三、算法分析

1、渐进符号

1.1 定义
  • Θ \Theta Θ 记号(渐近紧确界)
    Θ ( g ( n ) ) = { f ( n ) ; 存 在 正 常 量 c 1 , c 2 和 n 0 , 使 得 对 所 有 的 n > n 0 , 有 0 ≤ c 1 g ( n ) ≤ f ( n ) ≤ c 2 g ( n ) } \Theta(g(n))=\{f(n); 存在正常量c_1,c_2和n_0,使得对所有的n>n_0,有0\leq c_1g(n) \leq f(n) \leq c_2g(n) \} Θ(g(n))={f(n);c1,c2n0,使n>n0,0c1g(n)f(n)c2g(n)}

  • O O O 记号(渐近上界)
    O ( g ( n ) ) = { f ( n ) ; 存 在 正 常 量 c 和 n 0 , 使 得 对 所 有 的 n > n 0 , 有 0 ≤ f ( n ) ≤ c g ( n ) } O(g(n))=\{f(n); 存在正常量c和n_0,使得对所有的n>n_0,有0\leq f(n)\leq cg(n) \} O(g(n))={f(n);cn0,使n>n0,0f(n)cg(n)}

  • Ω \Omega Ω 记号(渐进下界)
    Ω ( g ( n ) ) = { f ( n ) : 存 在 正 常 量 c 和 n 0 , 使 得 对 所 有 的 n > n 0 , 有 0 ≤ c g ( n ) ≤ f ( n ) } \Omega(g(n)) = \{f(n):存在正常量c和n_0, 使得对所有的n>n_0,有0\leq cg(n) \leq f(n) \} Ω(g(n))={f(n):cn0,使n>n0,0cg(n)f(n)}

1.2 三个符号间的关系

f ( n ) = Ω ( g ( n ) ) f(n)=\Omega(g(n)) f(n)=Ω(g(n)) f ( n ) = O ( g ( n ) ) f(n) = O(g(n)) f(n)=O(g(n)),则有 f ( n ) = Θ ( g ( n ) ) f(n)=\Theta(g(n)) f(n)=Θ(g(n))

1.3 一些已知量间的渐进关系
1.4 题目
  • 假设 f ( n ) f(n) f(n) g ( n ) g(n) g(n) 都是渐近非负函数,使用 Θ \Theta Θ 记号的基本定义来证明 m a x ( f ( n ) , g ( n ) ) = Θ ( f ( n ) + g ( n ) ) max(f(n), g(n))=\Theta(f(n)+g(n)) max(f(n),g(n))=Θ(f(n)+g(n))

    因为 f ( n ) f(n) f(n) g ( n ) g(n) g(n) 均为渐近非负函数,因此有: f ( n ) ≥ 0 f(n)\geq 0 f(n)0 g ( n ) ≥ 0 g(n) \geq 0 g(n)0

    那么有: 0 ≤ 1 2 ( f ( n ) + g ( n ) ) ≤ m a x ( f ( n ) , g ( n ) ) ≤ f ( n ) + g ( n ) 0 \leq \frac12(f(n) + g(n)) \leq max(f(n), g(n)) \leq f(n) + g(n) 021(f(n)+g(n))max(f(n),g(n))f(n)+g(n)

    即:存在 c 1 = 1 2 ,    c 2 = 1 ,    n 0 = 0 c_1=\frac12,\;c_2=1,\;n_0=0 c1=21,c2=1,n0=0 使得当 n ≥ n 0 n\geq n_0 nn0 时,有:
    0 ≤ c 1 ( f ( n ) + g ( n ) ) ≤ m a x ( f ( n ) + g ( n ) ) ≤ c 2 ( f ( n ) + g ( n ) ) 0\leq c_1(f(n)+g(n)) \leq max(f(n)+g(n)) \leq c_2(f(n)+g(n)) 0c1(f(n)+g(n))max(f(n)+g(n))c2(f(n)+g(n))
    即: m a x ( f ( n ) ,    g ( n ) ) = Θ ( f ( n ) + g ( n ) ) max(f(n),\;g(n))=\Theta(f(n)+g(n)) max(f(n),g(n))=Θ(f(n)+g(n))

  • 证明:对任意常量 a a a b b b,其中 b > 0 b > 0 b>0,有: ( n + a ) b = Θ ( n b ) (n+a)^b=\Theta(n^b) (n+a)b=Θ(nb)

    1. a ≥ 0 a\geq0 a0 n > ∣ a ∣ n>|a| n>a 时,有: 0 ≤ n b ≤ ( n + a ) b ≤ ( 2 n ) b = 2 b n b 0\leq n^b\leq (n+a)^b \leq (2n)^b=2^bn^b 0nb(n+a)b(2n)b=2bnb
    2. a < 0 a<0 a<0 n ≥ ∣ 2 a ∣ n\geq |2a| n2a 时,有: 0 ≤ 2 − b n b = ( 1 2 n ) b ≤ ( n + a ) b ≤ n b 0\leq 2^{-b}n^b=(\frac12n)^b \leq (n+a)^b \leq n^b 02bnb=(21n)b(n+a)bnb

    综上所述,存在 c 1 = 2 − b ,    c 2 = 2 b ,    n ≥ ∣ a ∣ c_1=2^{-b},\;c_2=2^b,\;n\geq|a| c1=2b,c2=2b,na,使得下式成立:
    0 ≤ 2 − b n b < n b ≤ ( n + a ) b ≤ n b ≤ 2 b n b 0\leq 2^{-b}n^b < n^b \leq (n+a)^b \leq n^b \leq 2^bn^b 02bnb<nb(n+a)bnb2bnb
    即: ( n + a ) b = Θ ( n b ) (n+a)^b=\Theta(n^b) (n+a)b=Θ(nb)

2、传统分析方法

2.1 基本思想

通过计算每条语句的执行次数,后累加得到 T ( n ) T(n) T(n)

2.2 最好最坏情况下的时间复杂度分析

举例:插入排序的时间复杂度分析

3、递归算法的分析方法

3.1 T(n)的一般式
3.2 替换法(代入法)
  • 求解步骤

    1. 猜测解的形式
    2. 用数学归纳法求出解中的常数,并证明解是正确的
  • 注意

    要做出好的猜测要靠经验,那么这里有一个微妙的细节:

    有时你可能正确猜出了递归式解的渐近界,但莫名其妙的在归纳证明时失败了。问题常常出在归纳假设不够强,无法证出准确的界。当遇到这种障碍时,如果修改猜测,将它减去一个低阶的项,数学证明常常能顺利证明。后面会有题目例证。

3.3 递归树方法

通常可以使用递归树方法来猜测解,再用代入法来证明猜测的正确性

3.4 Master方法
  • 针对的问题形式

    T ( n ) = a T ( n / b ) + f ( n ) T(n)=aT(n/b)+f(n) T(n)=aT(n/b)+f(n)

  • 主定理

    a ≥ 1 a\geq 1 a1 b > 1 b > 1 b>1 是常数, f ( n ) f(n) f(n) 是一个函数, T ( n ) T(n) T(n) 是定义在非负整数上的递归式:
    T ( n ) = a T ( n / b ) + f ( n ) T(n)=aT(n/b)+f(n) T(n)=aT(n/b)+f(n)
    其中我们将 n / b n/b n/b 解释为 ⌊ n / b ⌋ \lfloor n/b \rfloor n/b ⌈ n / b ⌉ \lceil n/b \rceil n/b。那么 T ( n ) T(n) T(n) 有如下渐近界:

    1. 若对某个常数 ε > 0 \varepsilon>0 ε>0 f ( n ) = O ( n l o g b a − ε ) f(n)=O(n^{log_ba-\varepsilon}) f(n)=O(nlogbaε),则 T ( n ) = Θ ( n l o g b a ) T(n)=\Theta(n^{log_ba}) T(n)=Θ(nlogba)
    2. f ( n ) = Θ ( n l o g b a ) f(n)=\Theta(n^{log_ba}) f(n)=Θ(nlogba),则 T ( n ) = Θ ( n l o g b a l g n ) T(n)=\Theta(n^{log_ba}lgn) T(n)=Θ(nlogbalgn)
    3. 若对某个常数 ε > 0 \varepsilon>0 ε>0 f ( n ) = Ω ( n l o g b a + ε ) f(n)=\Omega(n^{log_ba+\varepsilon}) f(n)=Ω(nlogba+ε),且对某个常数 c < 1 c<1 c<1 和足够大的 n n n a f ( n / b ) ≤ c f ( n ) af(n/b)\leq cf(n) af(n/b)cf(n),则 T ( n ) = Θ ( f ( n ) ) T(n)=\Theta(f(n)) T(n)=Θ(f(n))
  • 注意

    主定理中的三种情况并未覆盖所有情况,在情况一和情况二中是存在间隙的,同样的,在情况二和情况三中也是存在间隙的,如果函数 f ( n ) f(n) f(n) 落在这两个间隙中,或者情况3的正则条件不成立,那么就不能使用主方法来求解递归式。

3.5 题目
  • 证明: T ( n ) = T ( n − 1 ) + n T(n)=T(n-1)+n T(n)=T(n1)+n 的解为 O ( n 2 ) O(n^2) O(n2)

    假设 T ( n ) = O ( n 2 ) T(n)=O(n^2) T(n)=O(n2),则有: T ( n ) ≤ c n 2 T(n)\leq cn^2 T(n)cn2 T ( n − 1 ) ≤ c ( n − 1 ) 2 T(n-1)\leq c(n-1)^2 T(n1)c(n1)2
    T ( n ) = T ( n − 1 ) + n ≤ c ( n − 1 ) 2 + n = c n 2 − ( 2 c − 1 ) n + c T(n)=T(n-1)+n \leq c(n-1)^2+n=cn^2-(2c-1)n+c T(n)=T(n1)+nc(n1)2+n=cn2(2c1)n+c
    由上式:当 c ≥ 1 c\geq1 c1 n ≥ 1 n\geq 1 n1时, − ( 2 c − 1 ) n + c ≤ 0 -(2c-1)n+c \leq 0 (2c1)n+c0 恒成立,故此时, T ( n ) ≤ c n 2 T(n)\leq cn^2 T(n)cn2 恒成立

  • 证明: T ( n ) = T ( ⌈ n / 2 ⌉ ) + 1 T(n)=T(\lceil n/2 \rceil)+1 T(n)=T(n/2)+1 的解为 O ( l g n ) O(lgn) O(lgn)

    假设 T ( n ) = O ( l g n ) T(n)=O(lgn) T(n)=O(lgn),则有: T ( n ) ≤ c l g n T(n)\leq clgn T(n)clgn T ( ⌈ n / 2 ⌉ ) ≤ c l g ( ⌈ n / 2 ⌉ ) T(\lceil n/2 \rceil) \leq clg(\lceil n/2 \rceil) T(n/2)clg(n/2)
    T ( n ) = T ( ⌈ n / 2 ⌉ ) + 1 ≤ c l g ( ⌈ n / 2 ⌉ ) + 1 ≤ c l g ( n + 2 2 ) + 2 = c l g ( n + 2 ) − ( c − 1 ) T(n)=T(\lceil n/2 \rceil)+1 \leq clg(\lceil n/2 \rceil) + 1 \leq clg(\frac{n+2}2)+2=clg(n+2)-(c-1) T(n)=T(n/2)+1clg(n/2)+1clg(2n+2)+2=clg(n+2)(c1)
    发现无法证明出来…

    假设 T ( n ) ≤ c l g ( n − 2 ) T(n)\leq clg(n-2) T(n)clg(n2),则有 T ( ⌈ n / 2 ⌉ ) ≤ c l g ( ⌈ n / 2 ⌉ − 2 ) ≤ c l g ( n + 2 2 − 2 ) = c l g ( n − 2 2 ) = c l g ( n − 2 ) − c T(\lceil n/2 \rceil)\leq clg(\lceil n/2 \rceil -2)\leq clg(\frac{n+2}2-2)=clg(\frac{n-2}2)=clg(n-2)-c T(n/2)clg(n/22)clg(2n+22)=clg(2n2)=clg(n2)c
    T ( n ) = T ( ⌈ n / 2 ⌉ ) + 1 ≤ c l g ( n − 2 ) − c + 1 ≤ c l g ( n − 2 ) T(n)=T(\lceil n/2 \rceil)+1 \leq clg(n-2)-c+1 \leq clg(n-2) T(n)=T(n/2)+1clg(n2)c+1clg(n2)
    n > 2 n>2 n>2 c ≥ 1 c\geq1 c1时,上式成立

    即可推出 T ( n ) ≤ c l g ( n − 2 ) ≤ c l g n T(n)\leq clg(n-2)\leq clgn T(n)clg(n2)clgn n > 2 n>2 n>2 c ≥ 1 c \geq 1 c1 时成立,即 T ( n ) = O ( l g n ) T(n)=O(lgn) T(n)=O(lgn) 在此情况下成立

    n = 2 n=2 n=2 T ( 2 ) = 2 T(2)=2 T(2)=2

    此时若要满足 T ( n ) ≤ c l g n T(n)\leq clgn T(n)clgn,则 T ( 2 ) = 2 ≤ c l g 2 = c T(2)=2\leq clg2=c T(2)=2clg2=c 可知 c ≥ 2 c\geq2 c2

    综上所述,当 c ≥ 2 c\geq2 c2 n > = 2 n>=2 n>=2 时,满足 T ( n ) ≤ c l g n T(n)\leq clgn T(n)clgn,即 T ( n ) = O ( l g n ) T(n)=O(lgn) T(n)=O(lgn)

  • 我们看到 T ( n ) = 2 T ( ⌊ n / 2 ⌋ ) + n T(n)=2T(\lfloor n/2 \rfloor)+n T(n)=2T(n/2)+n 的解为 O ( n l g n ) O(nlgn) O(nlgn)。证明 Ω ( n l g n ) \Omega(nlgn) Ω(nlgn) 也是这个递归式的解。从而得出结论:解为 Θ ( n l g n ) \Theta(nlgn) Θ(nlgn)

    假设 T ( n ) = Ω ( n l g n ) ≥ c n l g n T(n)=\Omega(nlgn)\geq cnlgn T(n)=Ω(nlgn)cnlgn,则有 T ( ⌊ n / 2 ⌋ ) ≥ c ⌊ n / 2 ⌋ l g ( ⌊ n / 2 ⌋ ) T(\lfloor n/2 \rfloor)\geq c\lfloor n/2 \rfloor lg(\lfloor n/2 \rfloor) T(n/2)cn/2lg(n/2)

    T ( n ) = 2 T ( ⌊ n / 2 ⌋ ) + n T(n)=2T(\lfloor n/2 \rfloor)+n T(n)=2T(n/2)+n

    ≥ 2 c ⌊ n / 2 ⌋ l g ( ⌊ n / 2 ⌋ ) + n \geq2c\lfloor n/2 \rfloor lg(\lfloor n/2 \rfloor)+n 2cn/2lg(n/2)+n

    ≥ c n l g ( n / 2 ) + n \geq cnlg(n/2)+n cnlg(n/2)+n

    ≥ c n l g n − c n + n \geq cnlgn - cn + n cnlgncn+n

    ≥ c n l g n − ( c − 1 ) n \geq cnlgn -(c-1)n cnlgn(c1)n

    ≥ c n l g n \geq cnlgn cnlgn

    0 < c ≤ 1 0 < c \leq 1 0<c1 时,上式成立,即 T ( n ) = Ω ( n l g n ) T(n)=\Omega(nlgn) T(n)=Ω(nlgn)

    因此,可得该递归式的解为 T ( n ) = Θ ( n l g n ) T(n)=\Theta(nlgn) T(n)=Θ(nlgn)

  • 用主方法求 T ( n ) = 2 T ( n / 4 ) + 1 T(n)=2T(n/4)+1 T(n)=2T(n/4)+1 的紧确界

    a = 2 ,    b = 4 ,    f ( n ) = 1 a=2,\;b=4,\;f(n)=1 a=2,b=4,f(n)=1

    存在 ε = 1 2 \varepsilon=\frac12 ε=21 使得 f ( n ) = 1 = n l o g b a − ε = n l o g 4 2 − 1 2 f(n)=1=n^{log_ba-\varepsilon}=n^{log_42-\frac12} f(n)=1=nlogbaε=nlog4221,所以 T ( n ) = Θ ( n l o g b a ) = Θ ( n 1 2 ) = Θ ( n ) T(n)=\Theta(n^{log_ba})=\Theta(n^\frac12)=\Theta(\sqrt{n}) T(n)=Θ(nlogba)=Θ(n21)=Θ(n )

  • 用主方法求 T ( n ) = 2 T ( n / 4 ) + n T(n)=2T(n/4)+\sqrt{n} T(n)=2T(n/4)+n

    a = 2 ,    b = 4 ,    f ( n ) = n 1 2 a=2,\; b=4,\; f(n)=n^\frac12 a=2,b=4,f(n)=n21

    f ( n ) = n 1 2 = n l o g b a = n l o g 4 2 = n 1 2 f(n)=n^\frac12=n^{log_ba}=n^{log_42}=n^\frac12 f(n)=n21=nlogba=nlog42=n21,故 T ( n ) = Θ ( n l o g b a l g n ) = Θ ( n l g n ) T(n)=\Theta(n^{log_ba}lgn)=\Theta(\sqrt{n}lgn) T(n)=Θ(nlogbalgn)=Θ(n lgn)

  • 用主方法求 T ( n ) = 2 T ( n / 4 ) + n T(n)=2T(n/4)+n T(n)=2T(n/4)+n 的紧确界

    a = 2 ,    b = 4 ,    f ( n ) = n a=2,\; b=4,\; f(n)=n a=2,b=4,f(n)=n

    存在 ε = 1 2 \varepsilon=\frac12 ε=21 使得 f ( n ) = n = n l o g b a + ε = n l o g 4 2 + 1 2 f(n)=n=n^{log_ba+\varepsilon}=n^{log_42+\frac12} f(n)=n=nlogba+ε=nlog42+21

    又: a f ( n / b ) = 2 f ( n / 4 ) = n 2 af(n/b)=2f(n/4)=\frac{n}2 af(n/b)=2f(n/4)=2n

    1 2 ≤ c < 1 \frac12 \leq c < 1 21c<1 时,对任意 n ≥ 1 n\geq1 n1 满足 a f ( n / b ) = n / 2 ≤ c f ( n ) = c n af(n/b)=n/2 \leq cf(n)=cn af(n/b)=n/2cf(n)=cn

    所以 T ( n ) = Θ ( f ( n ) ) = Θ ( n ) T(n)=\Theta(f(n))=\Theta(n) T(n)=Θ(f(n))=Θ(n)

  • 用主方法求 T ( n ) = 2 T ( n / 4 ) + n 2 T(n)=2T(n/4)+n^2 T(n)=2T(n/4)+n2 的紧确界

    a = 2 ,    b = 4 ,    f ( n ) = n 2 a=2,\; b=4,\; f(n)=n^2 a=2,b=4,f(n)=n2

    存在 ε = 3 2 \varepsilon=\frac32 ε=23 使得 f ( n ) = n 2 = n l o g b a + ε = n l o g 4 2 + 3 2 f(n)=n^2=n^{log_ba+\varepsilon}=n^{log_42+\frac32} f(n)=n2=nlogba+ε=nlog42+23

    又: a f ( n / b ) = 2 f ( n / 4 ) = n 2 8 af(n/b)=2f(n/4)=\frac{n^2}8 af(n/b)=2f(n/4)=8n2

    1 8 ≤ c < 1 \frac18\leq c < 1 81c<1 时,对任意 n ≥ 1 n \geq 1 n1 满足 a f ( n / b ) = n 2 8 ≤ c f ( n ) = c n 2 af(n/b)=\frac{n^2}8\leq cf(n) = cn^2 af(n/b)=8n2cf(n)=cn2

    所以 T ( n ) = Θ ( f ( n ) ) = Θ ( n 2 ) T(n)=\Theta(f(n))=\Theta(n^2) T(n)=Θ(f(n))=Θ(n2)

  • 主方法能应用于递归式 T ( n ) = 4 T ( n / 2 ) + n 2 l g n T(n)=4T(n/2)+n^2lgn T(n)=4T(n/2)+n2lgn 吗?请说明为什么可以或为什么不可以。给出这个递归式的渐近上界

    a = 4 ,    b = 2 ,    f ( n ) = n 2 l g n a=4,\;b=2,\;f(n)=n^2lgn a=4,b=2,f(n)=n2lgn

    n l o g b a = n 2 n^{log_ba}=n^2 nlogba=n2,该式置于情况2与情况3的间隙之中,无法使用主方法来求解

    可用画递归树的方式来求得该式的渐近上界为 O ( ( n l g n ) 2 ) O((nlgn)^2) O((nlgn)2)

    接着可以使用代入法来证明该解的正确性

    假设 T ( n ) = O ( ( n l g n ) 2 ) T(n)=O((nlgn)^2) T(n)=O((nlgn)2),有 T ( n ) ≤ c ( n l g n ) 2 T(n) \leq c(nlgn)^2 T(n)c(nlgn)2 T ( n 2 ) = c n 2 ( l g n − 1 ) 2 T(\frac{n}2)=cn^2(lgn-1)^2 T(2n)=cn2(lgn1)2
    T ( n ) ≤ c n 2 ( l g n − 1 ) 2 + n 2 l g n = c ( n l g n ) 2 − 2 c n 2 l g n + c n 2 + n 2 l g n = c ( n l g n ) 2 − ( 2 c − 1 ) n 2 l g n + c n 2 T(n)\leq cn^2(lgn-1)^2+n^2lgn=c(nlgn)^2-2cn^2lgn+cn^2+n^2lgn=c(nlgn)^2-(2c-1)n^2lgn+cn^2 T(n)cn2(lgn1)2+n2lgn=c(nlgn)22cn2lgn+cn2+n2lgn=c(nlgn)2(2c1)n2lgn+cn2
    由于 n 2 l g n n^2lgn n2lgn 的增长速率大于 n 2 n^2 n2,故 当 c > 1 2 c>\frac12 c>21 时,必然存在 n 0 > 0 n_0>0 n0>0,使得当 n > n 0 n>n_0 n>n0时, − ( 2 c − 1 ) n 2 l g n + c n 2 ≤ 0 -(2c-1)n^2lgn+cn^2\leq0 (2c1)n2lgn+cn20

    即此时 c ( n l g n ) 2 − ( 2 c − 1 ) n 2 l g n + c n 2 ≤ c ( n l g n ) 2 c(nlgn)^2-(2c-1)n^2lgn+cn^2 \leq c(nlgn)^2 c(nlgn)2(2c1)n2lgn+cn2c(nlgn)2

    故: T ( n ) ≤ c ( n l g n ) 2 T(n) \leq c(nlgn)^2 T(n)c(nlgn)2

    T ( n ) = O ( ( n l g n ) 2 ) T(n)=O((nlgn)^2) T(n)=O((nlgn)2) 得证

4、平摊分析方法

4.1 基本思想

求数据结构的一个操作序列中所执行的所有操作的平均时间,来评价操作的代价。摊还分析不同于平均情况分析,它并不涉及概率,它可以保证最坏情况下的每个操作的平均性能。

4.2 合计法(聚合分析)

利用聚合分析,我们证明对所有n,一个n个操作的序列最坏情况下花费的总时间是 T ( n ) T(n) T(n)。因此,在最坏情况下,每个操作的平均代价,或摊还代价为 T ( n ) / n T(n)/n T(n)/n

4.3 记账法(核算法)

用核算法进行摊还分析时,我们对不同操作赋予不同费用,该费用称为摊还代价。当一个操作的摊还代价超出实际代价时,则将差额存入特定对象,该差额称为信用,对于后续操作中摊还代价小于实际代价的情况时,就可以使用信用来支付差额。

因此,核算法是将一个操作的摊还代价分解为其实际代价和信用。

4.4 势函数方法

假设我们将对一个初始数据结构 D 0 D_0 D0 执行 n n n 个操作。对每个 i = 1 , 2 , . . . , n i=1,2,...,n i=1,2,...,n,令 c i c_i ci 为第 i i i 个操作的实际代价,令 D i D_i Di 为在数据结构 D i − 1 D_{i-1} Di1 上执行第 i i i 个操作得到的结果数据结构。势函数 Φ \Phi Φ 将每个数据结构 D i D_i Di 映射到一个实数 Φ ( D i ) \Phi(D_i) Φ(Di),此值即为关联到数据结构 D i D_i Di 的势。第 i i i 个操作的摊还代价 c ^ i \hat{c}_i c^i 用势函数 Φ \Phi Φ 定义为:
c ^ i = c i + Φ ( D i ) − Φ ( D i − 1 ) \hat{c}_i=c_i+\Phi(D_i)-\Phi(D_{i-1}) c^i=ci+Φ(Di)Φ(Di1)
那么,总摊还代价为:
∑ i = 1 n c ^ i = ∑ i = 1 n ( c i + Φ ( D i ) − Φ ( D i − 1 ) ) = ∑ i = 1 n c i + Φ ( D n ) − Φ ( D 0 ) \sum_{i=1}^n\hat{c}_i=\sum_{i=1}^n(c_i+\Phi(D_i)-\Phi(D_{i-1}))=\sum_{i=1}^nc_i+\Phi(D_n)-\Phi(D_0) i=1nc^i=i=1n(ci+Φ(Di)Φ(Di1))=i=1nci+Φ(Dn)Φ(D0)

4.5 动态表分析

5、算法正确性分析

5.1 循环不变式(*)
5.2 cut and paste方法
5.3 归纳法
5.4 贪心选择性质

四、最大流

1、流、流网络定义

  • 流网络

    流网络 G = ( V , E ) G=(V,E) G=(V,E) 是一个有向图,图中的每条边 ( u , v ) ∈ E (u, v)\in E (u,v)E 有一个非负的容量值 c ( u , v ) ≥ 0 c(u, v) \geq 0 c(u,v)0。而且,边集合 E E E 中若包含一条边 ( u , v ) (u,v) (u,v),则图中不存在反向边 ( v , u ) (v,u) (v,u),(ps: 若存在反向边,可以增加一个节点来消除反平行边)。

    ( u , v ) ∉ E (u,v) \notin E (u,v)/E,则 c ( u , v ) = 0 c(u,v)=0 c(u,v)=0,图中不允许自循环。

    s s s 为源点, t t t 为汇点

    对于图中任意节点 v v v,存在 s ⇝ v ⇝ t s \leadsto v \leadsto t svt,并且除源点外的每个节点都至少有一条进入的边,除了汇点外的每个节点都至少有一条出去的边。

  • G = ( V , E ) G=(V,E) G=(V,E) 是一个流网络,其容量函数为 c c c 。设 s s s 为网络中的源点, t t t 为网络中的汇点。 G G G 中的流是一个实值函数 f : V × V → R f:V \times V \rightarrow R f:V×VR,并满足下列三条性质:

    • **容量限制:**对于所有的 u , v ∈ V u,v\in V u,vV,有 f ( u , v ) ≤ c ( u , v ) f(u,v)\leq c(u,v) f(u,v)c(u,v)

    • **反对称性:**对于所有的 u , v ∈ V u,v\in V u,vV,有 f ( u , v ) = − f ( v , u ) f(u,v)=-f(v,u) f(u,v)=f(v,u)

    • **流量守恒:**对于所有的 u ∈ V − { s , t } u\in V-\{s,t\} uV{s,t},有:

    ∑ u ∈ V f ( u , v ) = 0 \sum_{u\in V}f(u,v)=0 uVf(u,v)=0

    一个流的值 ∣ f ∣ |f| f 的定义如下:
    ∣ f ∣ = ∑ v ∈ V f ( s , v ) − ∑ v ∈ V f ( v , s ) |f|=\sum_{v\in V}f(s,v)-\sum_{v\in V}f(v,s) f=vVf(s,v)vVf(v,s)

2、Ford-Fulkerson方法

  • 残存网络

    假定有一个网络流 G = ( V , E ) G=(V,E) G=(V,E),其源点为 s s s,汇点为 t t t 。设 f f f 为图 G G G 中的一个流。考虑节点对 u , v ∈ V u,v\in V u,vV,定义残存容量 c f ( u , v ) c_f(u,v) cf(u,v) 为:

    c f ( u , v ) = { c ( u , v ) − f ( u , v )      若 ( u , v ) ∈ E f ( v , u )       若 ( v , u ) ∈ E 0    其 他 c_f(u,v)=\left\{ \begin{aligned} c(u,v)-f(u,v)\;\;若(u,v)\in E \\ f(v,u)\qquad\qquad\;\;\,若(v,u)\in E \\ 0\qquad\;\qquad\qquad\qquad\qquad其他 \end{aligned} \right. cf(u,v)=c(u,v)f(u,v)(u,v)Ef(v,u)(v,u)E0
    给定一个流网络 G G G 和一个流 f f f,则由 f f f 所诱导的图 G G G 的残存网络为 G f = ( V ,    E f ) G_f=(V,\;E_f) Gf=(V,Ef),其中:
    E f = { ( u , v ) ∈ V × V : c f > 0 } E_f=\{(u,v)\in V\times V:c_f>0\} Ef={(u,v)V×Vcf>0}
    在残存网络中将流量推送回去称为抵消操作

  • 增广路经

    给定流网络 G = ( V ,    E ) G=(V,\;E) G=(V,E) 和流 f f f,增广路径 p p p 是残存网络 G f G_f Gf 中一条从源节点 s s s,到汇点 t t t 的一条简单路径。

    对于一条增广路径,我们能为它每条边增大的最大流量为路径 p p p 的残存容量:
    c f ( p ) = m i n { c f ( u , v ) :    ( u , v )    属 于 路 径    p } c_f(p)=min\{c_f(u,v): \; (u,v) \; 属于路径 \; p\} cf(p)=min{cf(u,v):(u,v)p}

  • 流网络的切割

    流网络 G = ( V ,    E ) G=(V,\;E) G=(V,E) 中的一个切割 ( S ,    T ) (S,\;T) (S,T) 将结点集合 V V V 划分为 S S S T = V − S T=V-S T=VS 两个集合,使得 s ∈ S ,    t ∈ T s\in S,\; t\in T sS,tT

  • 基本Ford-Fulkerson算法

FORD-FULKERSON(G, s, t)
    for each edge(u, v) in G, E:
		(u, v).f = 0 
    while there exists a path p from s to t in the redidual network Gf:
		c_f(p) = min{c_f(u, v): (u, v) is in p}
		for each edge(u, v) in p:
			if (u, v) in E:
				(u, v).f = (u, v) + c_f(p)
             else (v, u).f = (v, u).f - c_f(p)       

6、相关算法及时间

Ford-Fulkerson算法的运行时间为 O ( E ∣ f ∗ ∣ ) O(E|f^*|) O(Ef),其中 f ∗ f^* f 为最大流的数量

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值