Introduction to Algorithm-04-Amortized Analysis and Disjoint-Sets
Dynamic tables
Dynamic array
- 初始容量:向量从一个初始容量开始。
- 扩容条件:当向量的大小达到当前容量时,触发扩容。
- 倍增扩容:将当前容量加倍(例如,从 增加到 )。
- 数据复制:将现有元素复制到新的更大容量的存储空间中。
数据结构中的向量的倍增扩容的方法,在均摊分析下算法的时间复杂度为
- 插入操作:大多数插入操作只需在末尾添加元素,时间复杂度为 。
- 扩容操作:每次扩容时,需要进行 的复制操作。
- 均摊成本:在 次插入操作中,扩容操作发生的次数是对数级别的(即 次),因此每次插入的均摊成本为:
其中, 表示每次扩容时的元素复制次数。
Aggregate analysis
对于n个元素进行的所有操作进行求和,然后除以n,得到平均值
Increment a binary counter
问题描述:设计一个二进制计数器,初始值为0,每次加1,直到,然后重置为0
在分析的过程中发现,不是每一个比特位都会变化,分析发现:第位变化时的周期为。
The Accounting method
用核算法 (accounting method) 进行摊还分析时,我们对不同操作赋予不同费用,赋予某些操作的费用可能多于或少于其实际代价。
我们将赋予一个操作的费用称为它的摊还代价。当一个操作的摊还代价超出其实际代价时,我们将差额存入数据结构中的特定对象,存入的差额称为信用。
对于后续操作中摊还代价小于实际代价的情况,信用可以用来支付差额。因此,我们可以将一个操作的摊还代价分解为其实际代价和信用(存入的或用掉的)。不同的操作可能有不同的摊还代价。这种方法不同于聚合分析中所有操作都赋予相同摊还代价的方式。
每次操作都分配一个固定的费用,实际上可能会比实际的费用要多,剩余的费用可以用来支付后续的操作。正确的操作要求银行的存款总是非负的,即:
其中是分配的费用,是实际的费用,在满足前提的情况下使得尽量小。
Potential method
势能法的工作方式为,对一个数据结构分配一个势能函数,在每次操作时,势能函数的值会发生变化。势能函数的变化量可以看作是对操作的额外费用。对于每个操作,我们可以定义:
只需要即可满足在支付分析中要求的条件,不妨令
Data Structures for Disjoint Sets
并查集是一种用于处理不交集(Disjoint Sets)数据结构,支持以下操作:
- MakeSet:创建一个新的集合
- Find:确定元素属于哪个子集
- Union:将两个子集合并为一个
Linked-list reprsentation of disjoint sets
每个集合用一个链表表示,链表的头结点为集合的代表元素。每个元素都有一个指向其父节点的指针,根节点的父节点指向自己。
在这种情况下,Find操作的时间复杂度为,Union操作的时间复杂度为。在合并的过程中将较短的链表连接到较长的链表上。
上面的操作可以将复杂度降低为。在次操作中,其中个是MakeSet操作,个是Find和Union操作,时间复杂度为:
由于每一次更新指针一定是在较小的集合中,每个元素更新指针的次数不会超过
Disjoint set forests
每个集合用一棵树表示,树的根节点为集合的代表元素。每个元素都有一个指向其父节点的指针,根节点的父节点指向自己。每个节点都有一个秩(rank)属性,用于表示树的高度。
在上面的操作中,MakeSet操作的时间复杂度为,Union操作的时间复杂度为。
- Union by rank: 在合并两个集合时,将树的高度较小的树连接到高度较大的树上,维护两个树的高度
1 | |
- Path compression: 在Find操作中,将路径上的所有节点直接连接到根节点上,减少树的高度
1 | |
Analysis of union-find
Ackerman function
阿克曼函数是一个非常快速增长的函数,定义如下:
定义上面的函数的反函数有:
Analysis of union-find
使用势能方法案来分析均摊时间复杂度
对于每个节点 ,其势能 根据以下规则分配:
-
如果 是根节点或其秩为 0,则 。
-
否则,
其中:
- :阿克曼函数的反函数(Inverse Ackermann Function),增长极慢,在实际应用中几乎是常数。
- :节点 的级别,定义为最大的整数 ,满足 的父节点秩 ,其中 是阿克曼函数的第 阶迭代。
- :节点 在当前级别内的“迭代”次数,表示路径压缩过程中节点状态的微调。
- :节点 的秩,通常是树高度的上界(在使用按秩合并时)。
这种势能函数的设计反映了路径压缩和按秩合并对树结构的影响
Applications of Disjoint Sets
Connected Components
可以使用并查集来计算无向图的连通分量。每个顶点初始化为一个独立的集合,然后通过遍历边来合并顶点所在的集合。