平摊分析(算法导论)

平摊分析是一种算法分析方法,通过对操作序列整体考虑,得出每个操作的平均开销,而非仅关注单个操作。以动态表为例,插入操作在最坏情况下看似O(n),但实际序列中可以通过平摊分析得出总开销为O(n),每个操作平均为O(1)。动态表在删除和插入混合序列中,适当调整装载因子可保持良好性能。平摊分析还包括聚集分析和势能分析等方法,帮助我们更好地理解和评估算法性能。
摘要由CSDN通过智能技术生成

1.平摊分析是什么

平摊分析是一种算法分析的手法,其主要思路是:对若干条指令(通常O(n)条)整体进行考虑其时间复杂度(以获得更接近实际情况的时间复杂度),而不是逐一考虑执行每条指令所需的时间复杂度后再进行累加。

对于一个操作的序列来讲,平摊分析(Amortize Analysis)得出的是在特定问题中这个序列下每个操作的平摊开销。一个操作序列中,可能存在一、两个开销比较大的操作,在一般地分析下,如果割裂了各个操作的相关性或忽视问题的具体条件,那么操作序列的开销分析结果就可能会不够紧确,导致对于操作序列的性能做出不准确的判断。用平摊分析就可以得出更好的、更有实践指导意义的结果。因为这个操作序列中各个操作可能会是相互制约的,所以开销很大的那一、两个操作,在操作序列总开销中的贡献也会被削弱和限制。所以最终会发现,对于序列来讲,每个操作平摊的开销是比较小。平摊分析的输入是问题的具体条件以及若干个有相互关联的具体动作的序列,输出是,在该问题的条件下,这个动作序列的每一个动作(不管具体它是什么)的平摊性能开销并不等于最大开销动作的最坏时间(不再需要考虑具体动作,只需要知道每个动作可能是平摊小开销的)

下面我们来看一个关于动态表的具体例子:

我们经常会遇到这样的情况:无法预先知道有多少对象需要存储。因此无法准确地事先分配好足够的内存并保证内存是大致足够的。事先分配的内存要么可能不足,要么太多以致浪费。

对于这种情况,我们可以采用动态表的策略来应对。就是一开始分配一定量的内存A,如果在向这个内存内继续增加对象时发现空间不足的话,就重新分配一块比原来大的内存B(就定B比A要大两倍吧),把原内存A中所有的对象都复制到内存B中,然后把新加入的对象增加到B的空余位置中,最后把内存A释放掉。同样,如果从内存中称除某个对象时,发现此空间内所存的对象太少,出现空间浪费时,就分配一块新的更小的内存(先假设新内存是原内存的二分之一),把原内存中的对象复制过来,并释放原内存给其它的程序使用(C++标准库中的vector等,就用了这样的策略)。

我们先来看插入操作的伪代码:

TABLE-INSERT (T , x)
1 if size[T ] = 0 then
2 allocate table[T] with 1 slot
3 size[T] ← 1
4 if num[T] = size[T] then
5 allocate new-table with 2 · size[T] slots
6 insert all items in table[T] into new-table
7 free table[T]
8 table[T] → new-table
9 size[T] → 2 · size[T]
10 insert x into table[T]
11 num[T] → num[T] + 1
  在这个操作中,如果插入时,原内存块还有足够的空间,那就只要把新插入的x放到未使用的空间上(空间的使用是连续的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值