-
对某个数据结构执行大小为 n 的一个操作序列,若 i 为 2 的整数幂,则第 i 个操作的代价 为 i,否则为 1。请利用会计方法分析每次操作的平摊代价
对i不是2的整数幂,平摊代价为3.
1支付本操作
1在序列中本位置自身存款
1在序列中第一个没有存款的数据点进行存款
对i是2的整数幂,平摊代价为0,通过存款支付实际代价和平摊代价的差值。可以保证存款非负
则总的平摊代价为3n,每次操作平台代价为3 -
Bill 提出了一种叫做翻转堆栈的数据结构,翻转堆栈只支持 Flipping-Push() 函数。在每 次 Flipping-Push() 中,首先压栈,并检查堆栈中的对象数目数是否是 2 的幂(2^i )。如果 是,则堆栈中的所有对象将翻转。例如我们使用 Flipping-Push() 将对象 1,2,3,4 压入堆栈 中,堆栈中的内容(从底向上看)在每次压栈后为:
(1) ⇒ (2, 1) ⇒ (2, 1, 3) ⇒ (4, 3, 1, 2) Bill
请求你分别使用聚集分析、会计方法、势能方法分析 Flipping-Push() 函数的平摊代价 (amortized cost), 堆栈反转的代价等于堆栈现有对象数目
聚集分析:对第i次操作,若i=2^m,则进行堆反转,ci=i+i。否则ci=1
则平摊代价总和<=n+(2n-1)<=3n。平摊代价为3
会计法:
对i不是2的整数幂,平摊代价为3.
1支付本操作
1在序列中本位置自身存款
3在序列中第一个没有存款的数据点进行存款
对i是2的整数幂,平摊代价为0,当堆栈反转时,通过存款支付实际代价和平摊代价的差值。可以保证存款非负。
平摊代价总和<=3n,平摊代价为3
势能分析:
势能函数:
堆栈反转时,相当于再开辟一个新栈,将原栈数据push进去。即size(S)=2*num(S)
满足每次反转后为0,每次为2k时,为最大值=size(S)
φ(S)=2*num(S)-size(S)
分析:
进行反转时
ci=i+1=num(Si)+1=size(SI)/2+1
φ(Si)-φ(Si-1)=2num(Si)-size(Si)-2num(Si-1)+size(Si-1)
=2-size(Si)+size(Si-1)
= 2-1/2size(Si)
ci’=3
当不进行反转时,ci=1
φ(Si)-φ(Si-1)=2num(Si)-size(Si)-2num(Si-1)+size(Si-1)=2
ci’=3 -
有两个堆栈 A 和 B,都可以使用以下 5 种操作(A 大小为 n,B 大小为 m):
PushA(x):x 压入堆栈 A,实际代价 =1
PushB(x):x 压入堆栈 B,实际代价 =1MultiPopA(k): 从 A 中弹出 min{k, n} 个元素,实际代价 =min{k, n}
MultiPopB(k): 从 B 中弹出 min{k, m} 个元素,实际代价 =min{k, m}
Transfer(k): 从 A 中弹出元素并压入 B 中,直到转移 k 个元素或 A 为空,实际代价 = 转 移元素数目 (a)MultiPopA(k),MultiPopB(k),Transfer(k) 三种操作最坏情况下的时间复杂度为多少?
(b) 定义一个势能函数 Φ(n, m), 用它证明以上操作平摊代价为 O(1)
(a)O(n),O(m),O(n)
(b)势函数:
φ(A,B)=2numA+numB
当pushA时
ci=1
φ(Ai,Bi)-φ(Ai-1,Bi-1)=2
ci’=3
当pushB时
ci=1
φ(Ai,Bi)-φ(Ai-1,Bi-1)=1
ci’=2
当MultiPopA(k):
ci=k
φ(Ai,Bi)-φ(Ai-1,Bi-1)=-2k
ci’=-k
当MultiPopA(k):
ci=k
φ(Ai,Bi)-φ(Ai-1,Bi-1)=-k
ci’=0
Transfer(k):
ci=k
φ(Ai,Bi)-φ(Ai-1,Bi-1)=-k
ci’=0
算法设计练习题——平摊分析
最新推荐文章于 2020-12-22 13:23:25 发布