假设我有一个由n元素数组支持的堆栈,其成本为1,推出成本为1,从数组中取出一个元素,调整数组大小的成本是移动的元素数。
1)每次堆栈变满时,我会将当前n个元素复制到一个比之前大一个元素的新数组中。我的文字声称,一系列推送将导致总费用:
1 + 2 + 3 + ... + n
这是为什么?假设我的数组以n = 1开始。
我推,堆栈现已满(成本1) 我增加了数组的大小(n = 2,成本为2) 我推和堆栈现已满(成本为1) 我增加了数组的大小(n = 3,成本为4) ...
我错过了什么?
2)假设每次堆栈满时我将数组的大小加倍。现在我从一个1元素数组开始有一系列n次推送:
我推,堆栈现已满(成本为1) 我将数组大小加倍并复制1个元素(成本为2,n = 2) 我推和堆栈现已满(成本为1) 我将数组大小加倍并复制2个元素(成本为4,n = 4) ...
这种分析看起来是否正确?
对于一系列n次推送,它将产生1 + 2 + 1 + 4 + 1 + 8 + ... + 1 + 2 ^(n / 2)
答案 0 :(得分:1)
一切听起来都合理:
1)让我们从一个空堆栈开始,由一个初始大小n=1
的数组表示
cost = <push-cost> = 1
=&gt;阵列现已满了cost = <resize-cost> + <push-cost> = n + 1 = 2
=&gt; n := n + 1 = 2
cost = <resize-cost> + <push-cost> = n + 1 = 3
=&gt; n := n + 1 = 3
...依此类推,在推送1 + 2 + 3 + ... + n
元素时确实会导致n
的总费用。
2)您没有说出您的文字对此行为的说法,但计算方法类似:
cost = <push-cost> = 1
=&gt;阵列现已满了cost = <resize-cost> + <push-cost> = n + 1 = 2
=&gt; n := 2 * n = 2
cost = <resize-cost> + <push-cost> = n + 1 = 3
=&gt; n := 2 * n = 4
cost = <push-cost> = 1
=&gt;阵列现已满了cost = <resize-cost> + <push-cost> = n + 1 = 5
=&gt; n := 2 * n = 8
cost = <push-cost> = 1
cost = <push-cost> = 1
cost = <push-cost> = 1
=&gt;阵列现已满了cost = <resize-cost> + <push-cost> = n + 1 = 9
=&gt; n := 2 * n = 16
...导致总费用
1 + 2 + 3 + 1 + 5 + 1 + 1 + 1 + 9 + 1 + 1 + 1 + 1 + 1 + 1 + 1...
请注意,调整大小操作总是发生在元素2^n+1
上,然后是2^n-1
&#34; resize-free&#34;操作。因此,我们可以将其重写为(折叠+ 1
- 左侧链)
1 + 2 + 4 + 8 + 16 + ...
(非正式地)表示每次推送操作的O(n)
总费用或O(1)
的摊销费用。