基本思想(聚集方法需要精细分析,会计方法需要一步一步猜,势能方法需要构思势能函数)
聚集方法:分析整体的时间复杂度,每一步都假设代价相同,然后除以n
一般需要精细分析,并不是看一眼就行了的那种
会计方法:为不同的操作赋予不同的代价,然后按每一步的操作分析代价
设
c
i
c_i
ci和
α
i
\alpha_i
αi是操作
i
i
i的实际代价和平摊代价
∑
1
≤
i
≤
n
α
i
−
∑
1
≤
i
≤
n
c
i
≥
0
\sum_{1\le i\le n}{\alpha_i}-\sum_{1\le i\le n}{c_i}\ge 0
∑1≤i≤nαi−∑1≤i≤nci≥0必须对于任意
n
n
n个操作序列都成立
势能方法:为不同的操作赋予不同的代价,然后对整个问题分析代价
考虑在初始数据结构
D
0
D_0
D0上执行
n
n
n个操作,对于操作
i
i
i,操作
i
i
i的实际代价为
c
i
c_i
ci,操作
i
i
i将数据结构
D
i
−
1
D_{i-1}
Di−1变为
D
i
D_i
Di,数据结构
D
i
D_i
Di的势能是一个实数
ϕ
(
D
i
)
\phi(Di)
ϕ(Di),
ϕ
\phi
ϕ是一个正函数,操作
i
i
i的平摊代价:
α
i
=
c
i
+
ϕ
(
D
i
)
−
ϕ
(
D
i
−
1
)
\alpha_i=c_i+\phi(D_i)-\phi(D_{i-1})
αi=ci+ϕ(Di)−ϕ(Di−1),
n
n
n个操作的总平摊代价(必须是实际代价的上界)
∑
i
=
1
n
α
i
=
∑
i
=
1
n
(
c
i
+
ϕ
(
D
i
)
−
ϕ
(
D
i
−
1
)
)
=
∑
i
=
1
n
c
i
+
ϕ
(
D
n
)
−
ϕ
(
D
0
)
\sum_{i=1}^{n}\alpha_i=\sum_{i=1}^{n}(c_i+\phi(D_i)-\phi(D_{i-1}))=\sum_{i=1}^{n}c_i+\phi(D_n)-\phi(D_{0})
∑i=1nαi=∑i=1n(ci+ϕ(Di)−ϕ(Di−1))=∑i=1nci+ϕ(Dn)−ϕ(D0)
基本例题
1.栈的操作
操作
M
u
l
t
i
p
o
p
(
S
,
k
)
Multipop(S, k)
Multipop(S,k): 去掉
S
S
S的
k
k
k个顶对象, 当
∣
S
∣
<
k
|S|<k
∣S∣<k时弹出整个栈
M
u
l
t
i
p
o
p
(
S
,
k
)
(
1
)
W
h
i
l
e
n
o
t
S
T
A
C
K
−
E
M
P
T
Y
(
S
)
a
n
d
k
≠
0
D
o
(
2
)
P
o
p
(
S
)
;
(
3
)
k
←
k
−
1.
Multipop(S, k)\\ (1) While\quad not\quad STACK-EMPTY(S)\quad and\quad k\ne 0\quad Do\\ (2)\quad Pop(S);\\ (3)\quad k\leftarrow k-1.
Multipop(S,k)(1)WhilenotSTACK−EMPTY(S)andk=0Do(2)Pop(S);(3)k←k−1.
假设
P
o
p
Pop
Pop的代价是1,那么
M
u
l
t
i
p
o
p
(
S
,
k
)
Multipop(S, k)
Multipop(S,k)的代价就是
m
i
n
{
∣
S
∣
,
k
}
min\{|S|,k\}
min{∣S∣,k}
初始栈为空的 n n n个栈操作序列的分析 n n n个栈操作序列由 P u s h Push Push、 P o p Pop Pop和 M u l t i p o p Multipop Multipop组成
聚集方法:
(1)粗略分析:最坏情况下,每个操作都是
M
u
l
t
i
p
o
p
Multipop
Multipop,每个
M
u
l
t
i
p
o
p
Multipop
Multipop的代价最坏是
O
(
n
)
O(n)
O(n),操作系列的最坏代价为
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^2)
T(n)=O(n2),平摊代价为
T
(
n
)
/
n
=
O
(
n
)
T(n)/n=O(n)
T(n)/n=O(n)
(2)精细分析:一个对象在每次被压入栈后至多被弹出一次,在非空栈上调用
P
o
p
Pop
Pop的次数(包括在
M
u
l
t
i
p
o
p
Multipop
Multipop内的调用)至多为
P
u
s
h
Push
Push执行的次数, 即至多为
n
n
n,最坏情况下操作序列的代价为
T
(
n
)
≤
2
n
=
O
(
n
)
T(n)\le 2n=O(n)
T(n)≤2n=O(n),平摊代价
=
T
(
n
)
/
n
=
O
(
1
)
=T(n)/n=O(1)
=T(n)/n=O(1)
会计方法:
C
o
s
t
(
P
U
S
H
)
=
2
Cost(PUSH)=2
Cost(PUSH)=2一个1用来支付
P
U
S
H
PUSH
PUSH的开销,另一个1存储在压入栈的元素上,预支
P
O
P
POP
POP的开销,
C
o
s
t
(
P
O
P
)
=
0
Cost(POP)=0
Cost(POP)=0,
C
o
s
t
(
M
U
L
T
I
P
O
P
)
=
0
Cost(MULTIPOP)=0
Cost(MULTIPOP)=0这样
∑
1
≤
i
≤
n
α
i
−
∑
1
≤
i
≤
n
c
i
≥
0
\sum_{1\le i\le n}{\alpha_i}-\sum_{1\le i\le n}{c_i}\ge 0
∑1≤i≤nαi−∑1≤i≤nci≥0就成立了
势能方法:
ϕ
(
D
m
)
\phi(D_m)
ϕ(Dm)定义为栈
D
m
D_m
Dm中对象的个数,
ϕ
(
D
0
)
=
0
\phi(D_0)=0
ϕ(D0)=0,
D
0
D_0
D0是空栈
ϕ
(
D
i
)
≥
0
=
ϕ
(
D
0
)
\phi(D_i)\ge 0=\phi(D_0)
ϕ(Di)≥0=ϕ(D0), 因为栈中对象个数不会小于0。栈操作的平摊代价(设栈
D
i
−
1
D_{i-1}
Di−1中具有
s
s
s个对象)
P
U
S
H
PUSH
PUSH:
α
i
=
c
i
+
ϕ
(
D
i
)
−
ϕ
(
D
i
−
1
)
=
1
+
(
s
+
1
)
−
s
=
2
\alpha_i=c_i+\phi(D_i)-\phi(D_{i-1})=1+(s+1)-s=2
αi=ci+ϕ(Di)−ϕ(Di−1)=1+(s+1)−s=2;
P
O
P
:
α
i
=
c
i
+
ϕ
(
D
i
)
−
ϕ
(
D
i
−
1
)
=
1
+
(
s
−
1
)
−
s
=
0
POP: \alpha_i=c_i+\phi(D_i)-\phi(D_{i-1})=1+(s-1)-s=0
POP:αi=ci+ϕ(Di)−ϕ(Di−1)=1+(s−1)−s=0;
M
U
L
T
I
P
O
P
(
S
,
k
)
MULTIPOP(S, k)
MULTIPOP(S,k): 设
k
′
=
m
i
n
(
k
,
s
)
k'=min(k,s)
k′=min(k,s),
α
i
=
c
i
+
ϕ
(
D
i
)
−
ϕ
(
D
i
−
1
)
=
k
’
+
(
s
−
k
’
)
−
s
=
k
’
−
k
’
=
0
\alpha_i=c_i+\phi(D_i)-\phi(D_{i-1})=k’+(s-k’)-s=k’-k’=0
αi=ci+ϕ(Di)−ϕ(Di−1)=k’+(s−k’)−s=k’−k’=0
2.计数器加1算法
输入:
A
[
0..
k
−
1
]
A[0..k-1]
A[0..k−1],存储二进制数
x
x
x
输出:
A
[
0..
k
−
1
]
A[0..k-1]
A[0..k−1],存储二进制数
x
+
1
m
o
d
2
k
x+1 mod 2k
x+1mod2k
I
N
C
R
E
M
E
N
T
(
A
)
(
1
)
i
←
0
(
2
)
w
h
i
l
e
i
<
k
a
n
d
A
[
i
]
=
1
D
o
(
3
)
A
[
i
]
←
0
;
(
4
)
i
←
i
+
1
;
(
5
)
I
f
i
<
k
T
h
e
n
A
[
i
]
←
1
INCREMENT(A)\\ (1) i\leftarrow 0\\ (2) while\quad i<k\quad and\quad A[i]=1\quad Do\\ (3) \quad A[i]\leftarrow 0;\\ (4)\quad i\leftarrow i+1;\\ (5) If\quad i<k\quad Then\quad A[i]\leftarrow 1
INCREMENT(A)(1)i←0(2)whilei<kandA[i]=1Do(3)A[i]←0;(4)i←i+1;(5)Ifi<kThenA[i]←1
聚集方法:
(1)粗略分析:
每个
I
n
c
r
e
m
e
n
t
Increment
Increment的时间代价最多
O
(
k
)
O(k)
O(k),
n
n
n个
I
n
c
r
e
m
e
n
t
Increment
Increment序列的时间代价最多
O
(
k
n
)
O(kn)
O(kn),
n
n
n个
I
n
c
r
e
m
e
n
t
Increment
Increment平摊代价为
O
(
k
)
O(k)
O(k)
(2)精细分析:
一般地,对于
i
=
0
,
1
,
…
.
,
l
g
n
i=0, 1, …., lgn
i=0,1,….,lgn,
A
[
i
]
A[i]
A[i]改变次数为
n
/
2
i
n/2i
n/2i,对于
i
>
l
g
n
i>lgn
i>lgn,
A
[
i
]
A[i]
A[i]不发生改变 (因为
n
n
n个操作结果为
n
n
n,仅涉及
A
[
0
]
A[0]
A[0]至
A
[
l
g
n
]
A[lgn]
A[lgn]位)
T
(
n
)
=
∑
0
≤
i
≤
l
g
n
n
/
2
i
<
n
∑
0
≤
i
<
∞
1
/
2
i
=
2
n
=
O
(
n
)
T(n)= \sum_{0\le i\le lgn}n/2i<n\sum_{0\le i<\infin}1/2^i= 2n=O(n)
T(n)=∑0≤i≤lgnn/2i<n∑0≤i<∞1/2i=2n=O(n),每个
I
n
c
r
e
m
e
n
t
Increment
Increment操作的平摊代价为
O
(
1
)
O(1)
O(1)
会计方法:
每次一位被置1时,付2美元,1美元用于置1的开销 ,1美元存储在该“1”位上,用于支付其被置0时的开销 • 置0操作无需再付款
C
o
s
t
(
I
n
c
r
e
m
e
n
t
)
=
2
Cost(Increment)=2
Cost(Increment)=2,
∑
1
≤
i
≤
n
α
i
−
∑
1
≤
i
≤
n
c
i
≥
0
\sum_{1\le i\le n}{\alpha_i}-\sum_{1\le i\le n}{c_i}\ge 0
∑1≤i≤nαi−∑1≤i≤nci≥0就成立了
∑
1
≤
i
≤
n
c
i
≤
2
n
\sum_{1\le i\le n}{c_i}\le 2n
∑1≤i≤nci≤2n
势能方法:
ϕ
(
D
m
)
\phi(D_m)
ϕ(Dm)定义为第
m
m
m个操作后计数器中1的个数
b
m
b_m
bm,
ϕ
(
D
0
)
=
0
\phi(D_0)=0
ϕ(D0)=0,
D
0
D_0
D0中1的个数为0,
ϕ
(
D
i
)
≥
0
=
ϕ
(
D
0
)
\phi(D_i)\ge 0=\phi(D_0)
ϕ(Di)≥0=ϕ(D0), 因为计数器中1的个数不会小于0。
I
N
C
R
E
M
E
N
T
INCREMENT
INCREMENT操作的平摊代价,第
i
i
i个
I
N
C
R
E
M
E
N
T
INCREMENT
INCREMENT操作将
t
i
t_i
ti个1置0, 实际代价为
t
i
+
1
t_i+1
ti+1,计算操作
i
i
i的平摊代价
α
i
=
c
i
+
ϕ
(
D
i
)
−
ϕ
(
D
i
−
1
)
\alpha_i=c_i+\phi(D_i)-\phi(D_{i-1})
αi=ci+ϕ(Di)−ϕ(Di−1)
I
f
b
i
=
k
Ifb_i=k
Ifbi=k, 操作
i
就
r
e
s
e
t
s
i就resets
i就resets所有
k
k
k位, 所以
b
i
−
1
=
t
i
=
k
b_{i-1}=t_i=k
bi−1=ti=k,
I
f
b
i
>
0
,
则
b
i
=
b
i
−
1
−
t
i
+
1
If b_i>0, 则b_i=b_{i-1}-t_i+1
Ifbi>0,则bi=bi−1−ti+1于是
b
i
≤
b
i
−
1
−
t
i
+
1
;
ϕ
(
D
i
)
−
ϕ
(
D
i
−
1
)
=
b
i
−
b
i
−
1
≤
b
i
−
1
−
t
i
+
1
−
b
i
−
1
=
1
−
t
i
b_i\le b_{i-1}-t_i+1;\phi(D_i)-\phi(D_{i-1})=b_i-b_{i-1}\le b_{i-1}-t_i+1-b_{i-1}=1-t_i
bi≤bi−1−ti+1;ϕ(Di)−ϕ(Di−1)=bi−bi−1≤bi−1−ti+1−bi−1=1−ti平摊代价
α
i
=
c
i
+
ϕ
(
D
i
)
−
(
D
i
−
1
)
≤
(
t
i
+
1
)
+
(
1
−
t
i
)
=
2
\alpha_i=c_i+\phi(D_i)-(D_{i-1})\le(t_i+1)+(1-t_i)=2
αi=ci+ϕ(Di)−(Di−1)≤(ti+1)+(1−ti)=2
3.动态表的平摊分析
插入操作: T A B L E — I N S E R T ( T , x ) ( 1 ) I f s i z e [ T ] = 0 T h e n ( 2 ) 获 取 一 个 大 小 为 1 的 表 t a b l e [ T ] ; ( 3 ) s i z e [ T ] ← 1 ; ( 4 ) I f n u m [ T ] = s i z e [ T ] T h e n ( 5 ) 获 取 一 个 大 小 为 2 × s i z e [ T ] 的 新 表 n e w − t a b l e ; ( 6 ) 将 t a b l e [ T ] 中 元 素 插 入 n e w − t a b l e ; ( 7 ) 释 放 t a b l e [ T ] ; ( 8 ) t a b l e [ T ] ← n e w − t a b l e ; ( 9 ) s i z e [ T ] ← 2 × s i z e [ T ] ; ( 10 ) 将 x 插 入 t a b l e [ T ] ; ( 11 ) n u m [ T ] ← n u m [ T ] + 1 TABLE—INSERT(T, x)\\ (1) If\quad size[T]=0\quad Then\\ (2) \quad\quad获取一个大小为1的表table[T];\\ (3) size[T]\leftarrow 1;\\ (4) If num[T]=size[T] Then\\ (5) \quad\quad获取一个大小为2\times size[T]的新表new-table;\\ (6) \quad\quad将 table[T]中元素插入new-table;\\ (7) \quad\quad释放 table[T];\\ (8) \quad\quad table[T]\leftarrow new-table;\\ (9) \quad\quad size[T]\leftarrow 2\times size[T];\\ (10) 将 x插入table[T];\\ (11) num[T]\leftarrow num[T]+1 TABLE—INSERT(T,x)(1)Ifsize[T]=0Then(2)获取一个大小为1的表table[T];(3)size[T]←1;(4)Ifnum[T]=size[T]Then(5)获取一个大小为2×size[T]的新表new−table;(6)将table[T]中元素插入new−table;(7)释放table[T];(8)table[T]←new−table;(9)size[T]←2×size[T];(10)将x插入table[T];(11)num[T]←num[T]+1
聚集方法:
精细分析,第
i
i
i次操作的代价
C
i
C_i
Ci,如果
i
−
1
=
2
m
i - 1=2^m
i−1=2m,
C
i
=
i
C_i=i
Ci=i;否则
C
i
=
1
C_i=1
Ci=1;
n
n
n次
T
A
B
L
E
—
I
N
S
E
R
T
TABLE—INSERT
TABLE—INSERT操作的总代价为
∑
i
=
1
n
c
i
≤
n
+
∑
j
=
1
⌊
l
o
g
n
⌋
2
j
<
n
+
2
n
=
3
n
\sum_{i=1}^{n}c_i\le n+\sum_{j=1}^{\lfloor logn\rfloor}2^j<n+2n=3n
∑i=1nci≤n+∑j=1⌊logn⌋2j<n+2n=3n
会计方法:
每次执行
T
A
B
L
E
—
I
N
S
E
R
T
TABLE—INSERT
TABLE—INSERT平摊代价为3;1支付第11步中的基本插入操作的实际代价;1作为自身的存款;1存入表中第一个没有存款的数据上
势能方法:
ϕ
(
T
)
=
2
∗
n
u
m
[
T
]
−
s
i
z
e
[
T
]
\phi(T)=2*num[T]-size[T]
ϕ(T)=2∗num[T]−size[T]第i次操作的平摊代价,如果发生扩张,
c
i
=
3
c_i=3
ci=3,如果未发生扩张,
c
i
=
0
c_i=0
ci=0
收缩操作:
改进的收缩策略(允许装载因子低于1/2 )满表中插入数据项时,将表扩大一倍;删除数据项引起表不足1/4满时,将表缩小为原表的一半;扩张和收缩过程都使得表的装载因子变为1/2;表的装载因子的下界是1/4
ϕ
(
T
)
=
2
⋅
n
u
m
[
T
]
−
s
i
z
e
[
T
]
,
α
(
T
)
≥
1
/
2
;
s
i
z
e
[
T
]
/
2
−
n
u
m
[
T
]
,
α
[
T
]
<
1
/
2
\phi(T)=2\cdot num[T]-size[T],\alpha(T)\ge 1/2;size[T]/2-num[T],\alpha[T]<1/2
ϕ(T)=2⋅num[T]−size[T],α(T)≥1/2;size[T]/2−num[T],α[T]<1/2
作用于一动态表上的
n
n
n个操作的实际时间为
O
(
n
)
O(n)
O(n)
4.斐波那契堆性能平摊分析
一系列树,每棵树均是一个极小堆;一个指针,指向最小元素; 一些标记顶点。用于保持堆的“扁平结构”;标记的具体含义是:
x
x
x被标记,如果它以前是树根,但堆操作过程中变成其他结点的孩子且失去过孩子。
n
n
n : 堆
H
H
H中数据元素的个数
r
a
n
k
(
x
)
rank(x)
rank(x) : 堆中结点
x
x
x的孩子数
r
a
n
k
(
H
)
rank(H)
rank(H) : 堆
H
H
H的所有结点中的最大孩子数
t
(
H
)
t(H)
t(H) :堆
H
H
H中树的棵数
m
a
r
k
(
H
)
mark(H)
mark(H) :堆
H
H
H中被标记顶点的个数
ϕ
(
H
)
=
t
(
H
)
+
2
⋅
m
a
r
k
(
H
)
\phi(H)=t(H)+2\cdot mark(H)
ϕ(H)=t(H)+2⋅mark(H):势能函数
插入操作的过程:以新结点为根,创建一棵新树;将新的树插入树根双向链表;如有必要,更新最小元素指针,平摊代价 O ( 1 ) O(1) O(1)
Delete_min操作过程:删除最小元素;将其所有孩子链入双向链表,更新最小元素指针,实际开销 O ( t ( H ) + r a n k ( x ) ) O(t(H)+rank(x)) O(t(H)+rank(x));合并双向链表中的树根,使得没有树根具有相同 r a n k rank rank。平摊代价$O(rank(H))$
键值减小操作:若减小键值后,堆性质仍成立,则仅需减小键值;否则, 将 x x x子树剪切下来插入双向链表,若 x x x的父结点 p p p未标记,标记其父结点,否则,剪切 p p p插入双向链表,将 p p p置为未标记结点(递归过程)。实际开销 O ( c ) O(c) O(c),平摊代价 O ( 1 ) O(1) O(1),操作完成后的堆记为 H ′ H' H′,操作前的堆记为 H H H, t ( H ′ ) ≤ t ( H ) + c t(H' )\le t(H)+c t(H′)≤t(H)+c; m a r k ( H ′ ) = m a r k ( H ) − c + 2 mark(H')=mark(H)-c+2 mark(H′)=mark(H)−c+2; Δ ϕ ( H ) = c + 2 ( − c + 2 ) = 4 − c \Delta\phi(H) =c+2(-c+2)=4-c Δϕ(H)=c+2(−c+2)=4−c
删除操作的平摊代价 O ( r a n k ( H ) ) O(rank(H)) O(rank(H)):先将节点 x x x的键值减小为 − ∞ -\infin −∞,则 x x x将出现在堆顶,平摊代价 O ( 1 ) O(1) O(1);调用 d e l e t e m i n delete_min deletemin删除堆顶元素,平摊代价 O ( r a n k ( H ) ) O(rank(H)) O(rank(H))。
设 x x x是斐波那契堆中的任意结点,记 k = r a n k ( x ) k=rank(x) k=rank(x)。设 y 1 , y 2 , . . . , y k y_1,y_2,...,y_k y1,y2,...,yk是结点 x x x的所有孩子结点且恰好按其成为 x x x的孩子的先后次序列出,则 r a n k ( y 1 ) ≥ 0 rank(y_1)\ge0 rank(y1)≥0,且 r a n k ( y i ) ≥ i − 2 rank(y_i)\ge i-2 rank(yi)≥i−2对 i = 2 , 3 , . . . , k i=2,3,...,k i=2,3,...,k成立
证明.当 y i y_i yi成为 x x x的孩子时, x x x已有孩子 y 1 , y 2 , . . . , y i − 1 y_1,y_2,...,y_{i-1} y1,y2,...,yi−1,故 r a n k ( x ) = i − 1 rank(x)=i-1 rank(x)=i−1; y i y_i yi要成为 x x x的孩子,需满足 r a n k ( y i ) = r a n k ( x ) = i − 1 rank(y_i)=rank(x)=i-1 rank(yi)=rank(x)=i−1
设 x x x是斐波那契堆中的任意结点,记 k = r a n k ( x ) k=rank(x) k=rank(x),则 x x x所在的极小堆中至少有 ( 1 + 5 2 ) k − 2 (\frac{1+\sqrt{5}}{2})^{k-2} (21+5)k−2个结点
证明:根据引理1,用归纳法统计 x x x及其子孙结点的个数有 s k = 1 + s 0 + s 0 + . . . + s k − 2 ≥ 1 + 1 + F ( 0 ) + F ( 1 ) + . . . + F ( k − 2 ) ≥ 1 + F ( k ) ≥ ( 1 + 5 2 ) k − 2 s_k=1+s_0+s_0+...+s_{k-2}\ge1+1+F(0)+F(1)+...+F(k-2)\ge1+F(k)\ge(\frac{1+\sqrt{5}}{2})^{k-2} sk=1+s0+s0+...+sk−2≥1+1+F(0)+F(1)+...+F(k−2)≥1+F(k)≥(21+5)k−2
设 H H H是含有 n n n个结点的斐波那契堆,则 r a n k ( H ) = O ( l o g n ) rank(H)=O(logn) rank(H)=O(logn)
5.并查集性能平摊分析
M
a
k
e
S
e
t
(
x
)
MakeSet(x)
MakeSet(x)操作执行时定义结点
x
x
x的秩为0
F
i
n
d
Find
Find操作不改变任意顶点的秩
U
n
i
o
n
(
x
,
y
)
Union(x,y)
Union(x,y)分两种情况修改结点的秩:情形
a
a
a:
r
a
n
k
(
x
)
=
r
a
n
k
(
y
)
rank(x)=rank(y)
rank(x)=rank(y)。此时,令
x
x
x指向
y
y
y且
y
y
y是并集的代表元素,
r
a
n
k
(
y
)
rank(y)
rank(y)增加1,
r
a
n
k
(
x
)
rank(x)
rank(x)不变(其他结点的秩也保持不变);情形
b
b
b:
r
a
n
k
(
x
)
<
r
a
n
k
(
y
)
rank(x)<rank(y)
rank(x)<rank(y)。此时,令
x
x
x指向
y
y
y且
y
y
y是并集的代表元素,
r
a
n
k
(
y
)
rank(y)
rank(y)和
r
a
n
k
(
x
)
rank(x)
rank(x)保持不变(其他结点的秩也保持不变)
U N I O N ( x , y ) ( 1 ) L I N K ( F I N D ( x ) , F I N D ( y ) ) M A K E − S E T ( x ) ( 1 ) r a n k [ x ] ← 0 ( 2 ) p [ x ] ← x F I N D ( x ) ( 1 ) Q ← ∅ ( 2 ) W h i l e x ≠ p [ x ] D o ( 3 ) 将 x 插 入 Q ; ( 4 ) x ← p [ x ] ; ( 5 ) F o r ∀ y ∈ Q d o ( 6 ) p [ y ] ← x ; ( 7 ) 输 出 x L I N K ( x , y ) ( 1 ) i f r a n k [ x ] > r a n k [ y ] t h e n ( 2 ) p [ y ] ← x ( 3 ) e l s e p [ x ] ← y ( 4 ) i f r a n k [ x ] = r a n k [ y ] t h e n ( 5 ) r a n k [ y ] ← r a n k [ y ] + 1 UNION(x,y)\\ (1) LINK(FIND(x),FIND(y))\\ MAKE-SET(x)\\ (1) rank[x]\leftarrow 0\\ (2) p[x]\leftarrow x\\ FIND(x)\\ (1) Q\leftarrow \emptyset\\ (2) While\quad x\ne p[x]\quad Do\\ (3) \quad 将x插入Q;\\ (4) \quad x\leftarrow p[x];\\ (5) For\quad \forall y\in Q\quad do\\ (6) \quad p[y]\leftarrow x;\\ (7) 输出x\\ LINK(x,y)\\ (1) if\quad rank[x]>rank[y]\quad then\\ (2) \quad p[y]\leftarrow x\\ (3) else\quad p[x]\leftarrow y\\ (4) if\quad rank[x]=rank[y]\quad then\\ (5) \quad rank[y] \leftarrow rank[y] +1 UNION(x,y)(1)LINK(FIND(x),FIND(y))MAKE−SET(x)(1)rank[x]←0(2)p[x]←xFIND(x)(1)Q←∅(2)Whilex=p[x]Do(3)将x插入Q;(4)x←p[x];(5)For∀y∈Qdo(6)p[y]←x;(7)输出xLINK(x,y)(1)ifrank[x]>rank[y]then(2)p[y]←x(3)elsep[x]←y(4)ifrank[x]=rank[y]then(5)rank[y]←rank[y]+1
对于含有
n
n
n个结点的并查集,秩具有如下性质:
(1) 如果
x
≠
p
(
x
)
x\ne p(x)
x=p(x),则
r
a
n
k
(
x
)
<
r
a
n
k
(
p
(
x
)
)
rank(x) < rank(p(x))
rank(x)<rank(p(x))
(2)
r
a
n
k
(
x
)
rank(x)
rank(x)的初始值为0,缓慢递增直到
x
x
x不再是集合的代表 元素,此后保持不变
(3)对于任意
x
x
x,
r
a
n
k
(
p
(
x
)
)
rank(p(x))
rank(p(x))是在操作过程中单调缓慢递增
(4)
r
a
n
k
(
x
)
≤
n
−
1
rank(x)\le n-1
rank(x)≤n−1对任意结点成立
阿克曼函数是定义在
k
≥
0
,
j
≥
1
k\ge0, j\ge1
k≥0,j≥1上的递归函数
A
k
(
j
)
=
{
j
+
1
如
果
k
=
0
A
k
−
1
(
j
+
1
)
(
j
)
如
果
k
≥
1
A_k(j)=\left\{ \begin{array}{rcl} j+1 & & {如果k=0}\\ A_{k-1}^{(j+1)}(j) & & {如果k\ge1} \end{array} \right.
Ak(j)={j+1Ak−1(j+1)(j)如果k=0如果k≥1
k
k
k层, 层越大,增长越快;
j
j
j迭代次数,迭代次数越大,增长越快
阿克曼函数的逆函数定义为
α
(
n
)
=
m
i
n
{
k
∣
A
k
(
1
)
≥
n
}
\alpha(n) =min \{k | A_k(1)\ge n\}
α(n)=min{k∣Ak(1)≥n}
对并查集中的每个结点
x
x
x,定义
L
e
v
e
l
(
x
)
=
m
a
x
{
k
∣
r
a
n
k
(
p
(
x
)
)
≥
A
k
(
r
a
n
k
(
x
)
)
}
Level(x) = max\{k | rank(p(x)) \ge A_k(rank(x))\}
Level(x)=max{k∣rank(p(x))≥Ak(rank(x))}
I
t
e
r
(
x
)
=
m
a
x
{
i
∣
A
L
e
v
e
(
x
)
(
i
)
(
r
a
n
k
(
x
)
)
≤
r
a
n
k
(
p
(
x
)
)
}
Iter(x) = max\{i | A_{Leve(x)}^{(i)}(rank(x))\le rank(p(x))\}
Iter(x)=max{i∣ALeve(x)(i)(rank(x))≤rank(p(x))}
0
≤
L
e
v
e
l
(
x
)
<
α
(
n
)
0\le Level(x)<\alpha(n)
0≤Level(x)<α(n), 且
L
e
v
e
l
(
x
)
Level(x)
Level(x)随时间递增
1
≤
I
t
e
r
(
x
)
≤
r
a
n
k
(
x
)
1\le Iter(x)\le rank(x)
1≤Iter(x)≤rank(x), 且只要
L
e
v
e
l
(
x
)
Level(x)
Level(x)不变则
I
t
e
r
(
x
)
Iter(x)
Iter(x)不变或增大
只要
L
e
v
e
l
(
x
)
Level(x)
Level(x)不变则
I
t
e
r
(
x
)
Iter(x)
Iter(x)不变或增大
ϕ
q
(
x
)
=
{
α
(
n
)
⋅
r
a
n
k
(
x
)
若
x
是
树
根
或
者
r
a
n
k
(
x
)
=
0
[
α
(
n
)
−
L
e
v
e
l
(
x
)
]
⋅
r
a
n
k
(
x
)
−
I
t
e
r
(
x
)
若
x
不
是
树
根
且
r
a
n
k
(
x
)
≥
0
\phi_q(x)=\left\{ \begin{array}{rcl} \alpha(n)\cdot rank(x) & & {若x是树根或者rank(x)=0}\\ [\alpha(n)-Level(x)]\cdot rank(x)-Iter(x) & & {若x不是树根且rank(x)\ge0} \end{array} \right.
ϕq(x)={α(n)⋅rank(x)[α(n)−Level(x)]⋅rank(x)−Iter(x)若x是树根或者rank(x)=0若x不是树根且rank(x)≥0
0
≤
ϕ
q
(
x
)
≤
α
(
n
)
r
a
n
k
(
x
)
0\le\phi_q(x)\le\alpha(n)rank(x)
0≤ϕq(x)≤α(n)rank(x)
若
x
x
x不是树根,第
q
+
1
q+1
q+1个操作是
U
n
i
o
n
Union
Union或
F
i
n
d
Find
Find,则
ϕ
q
+
1
(
x
)
≤
ϕ
q
(
x
)
\phi_{q+1}(x)\le\phi_q(x)
ϕq+1(x)≤ϕq(x)
M
a
k
e
_
S
e
t
Make\_Set
Make_Set操作的平摊代价为
O
(
1
)
O(1)
O(1)
U
n
i
o
n
(
y
,
z
)
Union(y,z)
Union(y,z)操作的平摊代价为
Θ
(
α
(
n
)
)
\Theta(\alpha(n))
Θ(α(n))
F
i
n
d
(
x
)
Find(x)
Find(x)操作的平摊代价为
Θ
(
α
(
n
)
)
\Theta(\alpha(n))
Θ(α(n))
在并查集上执行m个操作的时间复杂度为
O
(
m
α
(
n
)
)
O(m\alpha(n))
O(mα(n))
参考:哈工大算法设计与分析PPT