【数学】平摊分析与动态表问题

本文探讨了动态表的插入策略,通过聚集分析、记账法和势函数法,计算了均摊复杂度。随后扩展到带删除操作的场景,设计了针对装载率的势函数,解决了数据膨胀和收缩的问题。

普通的动态表问题

我们需要用一个数据结构存储一些数据,但并不知道数据有多少个,所以也不知道申请多少空间合适。因此,我们采取了动态申请空间的策略,假设现在表的大小为sizesizesize,数据数为numnumnum
num<sizenum<sizenum<size时需要添加一个数据,直接加入即可,单次操作复杂度为1。
num=sizenum=sizenum=size时需要添加一个数据,则申请一个大小为2size2size2size的空间,然后将原来的numnumnum个数加上新加的数据都放进新空间里,复杂度为num+1num+1num+1
假设插入nnn次,那么这样一个数据结构的均摊复杂度是多少呢?

朴素的分析是,单次操作是O(n)O(n)O(n)的,操作数是O(n)O(n)O(n)的,所以是O(n2)O(n^2)O(n2)
这是一个很松的上界,可以做更好的估计。

采用聚集分析的话,当i−1i-1i1为2的次幂时,ci=ic_i=ici=i。其他时候ci=1c_i=1ci=1
所以总代价∑i=0nci≤n+∑i=1⌊log⁡n⌋2i≤3n\sum_{i=0}^nc_i \leq n+\sum_{i=1}^{\lfloor \log n \rfloor} 2^i \leq 3ni=0ncin+i=1logn2i3n
平摊代价3nn=3\frac{3n}{n}=3n3n=3

有了这个启发后,我们还可以设计记账法来分析。
一次插入的记账为3,其中1的代价给这次新插的数用,1的代价存款在新插的数上,1的代价给一个没有存款的数据。一次扩张后到下一次扩张前,新插的数据的个数和旧的数据个数是相等的,所以每次扩张时,动态表内的所有数上均有1的存款,那么换空间的复杂度只需要消耗这些存款了。

最后,考虑势函数法。
决定势函数的只有两个东西,sizesizesizenumnumnum,不妨先待定系数,设Φ(T)=anum+bsize\Phi(T)=anum+bsizeΦ(T)=anum+bsize
首先,我们考虑触发表扩张的一个操作,需要让它的平摊代价为常数。这里的numnumnumsizesizesize设为添加新数据前的:

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值