忘记了密码?新用户?<一个href="//www.parkandroid.com/account/signup/?signup=true&next=/wiki/amortized-analysis/" id="problem-signup-link-alternative" class="btn-link ax-click" data-ax-id="clicked_signup_from_generic_modal" data-ax-type="button" data-next="/wiki/amortized-analysis/">报名
现有的用户?<一个href="//www.parkandroid.com/account/login/?next=/wiki/amortized-analysis/" id="problem-login-link-alternative" class="btn-link ax-click" data-ax-id="clicked_login_from_generic_modal" data-ax-type="button" data-is_modal="true" data-next="/wiki/amortized-analysis/">登录
已经有账户了?<一个href="//www.parkandroid.com/account/login/?next=/wiki/amortized-analysis/" class="ax-click" data-ax-id="clicked_signup_modal_login" data-ax-type="link">日志在这里。
平摊分析是一种分析与数据结构相关的成本的方法,该数据结构可以在一段时间内平均掉最差的操作。通常,一个数据结构有一个特别昂贵的操作,但它并不经常被执行。不应该仅仅因为一个很少执行的操作是昂贵的,就将该数据结构标记为昂贵的结构。 平摊分析是用来平均最坏情况下代价高昂的操作。从成本的角度来看,数据结构最糟糕的情况是操作的顺序绝对最差。一旦找到排序,就可以对操作求平均。 摊销分析主要有三种类型:汇总分析、核算方法和潜在方法。
平摊分析是用来平均最坏情况下代价高昂的操作。从成本的角度来看,数据结构最糟糕的情况是操作的顺序绝对最差。一旦找到排序,就可以对操作求平均。 摊销分析主要有三种类型:汇总分析、核算方法和潜在方法。
摊销分析主要有三种类型:汇总分析、核算方法和潜在方法。
平摊分析是什么以及为什么使用平摊分析背后的直觉很重要。从本质上讲,这可以归结为对数据结构的“公平”。如果一个不常见的错误操作不会破坏数据结构。从技术上讲,我们想要了解数据结构在实际中是如何执行的,平摊分析通过给我们提供数据结构随时间变化的准确描述来帮助我们做到这一点。只看每个操作的最坏情况可能太悲观了,平摊分析可以让我们更清楚地了解发生了什么。 假设你想为烘焙义卖做一个蛋糕。蛋糕的制作相当复杂,但基本上有两个主要步骤: 把面糊(快)。 用烤箱烤(慢一点,一次只能放一个蛋糕)。 与烘焙相比,混合面糊花费的时间相对较少。然后,你反思蛋糕的制作过程。在决定是慢、中还是快时,您选择中,因为您将慢操作和快操作进行平均,从而得到中操作。 现在假设你想做100个蛋糕。要烤100个蛋糕,你有两种选择。你可以为一个单一的蛋糕混合面糊,烤它,重复。或者,你可以把所有100个蛋糕的面糊混合在一起,然后一个接一个地烘烤它们。这些方法是慢、中还是快? 平摊分析告诉我们,这两种方法都应该被描述为“中等”,即使你可能要连续烤100个蛋糕.即使您可能需要连续处理100个慢操作,但它们之前有100个快操作,因此平均值仍然是中等。 最坏情况是指不可能想象出更糟糕的一系列事件。例如,跳过混合面糊的操作,简单地烤100个蛋糕是没有任何意义的。这是一个缓慢的烘焙过程,但没有任何意义,所以不值得分析。蛋糕烘焙过程是一个中间过程,因为混合蛋糕糊和烘焙蛋糕有一个逻辑顺序,不能逆转。
假设你想为烘焙义卖做一个蛋糕。蛋糕的制作相当复杂,但基本上有两个主要步骤: 把面糊(快)。 用烤箱烤(慢一点,一次只能放一个蛋糕)。 与烘焙相比,混合面糊花费的时间相对较少。然后,你反思蛋糕的制作过程。在决定是慢、中还是快时,您选择中,因为您将慢操作和快操作进行平均,从而得到中操作。 现在假设你想做100个蛋糕。要烤100个蛋糕,你有两种选择。你可以为一个单一的蛋糕混合面糊,烤它,重复。或者,你可以把所有100个蛋糕的面糊混合在一起,然后一个接一个地烘烤它们。这些方法是慢、中还是快? 平摊分析告诉我们,这两种方法都应该被描述为“中等”,即使你可能要连续烤100个蛋糕.即使您可能需要连续处理100个慢操作,但它们之前有100个快操作,因此平均值仍然是中等。
与烘焙相比,混合面糊花费的时间相对较少。然后,你反思蛋糕的制作过程。在决定是慢、中还是快时,您选择中,因为您将慢操作和快操作进行平均,从而得到中操作。 现在假设你想做100个蛋糕。要烤100个蛋糕,你有两种选择。你可以为一个单一的蛋糕混合面糊,烤它,重复。或者,你可以把所有100个蛋糕的面糊混合在一起,然后一个接一个地烘烤它们。这些方法是慢、中还是快? 平摊分析告诉我们,这两种方法都应该被描述为“中等”,即使你可能要连续烤100个蛋糕.即使您可能需要连续处理100个慢操作,但它们之前有100个快操作,因此平均值仍然是中等。
现在假设你想做100个蛋糕。要烤100个蛋糕,你有两种选择。你可以为一个单一的蛋糕混合面糊,烤它,重复。或者,你可以把所有100个蛋糕的面糊混合在一起,然后一个接一个地烘烤它们。这些方法是慢、中还是快? 平摊分析告诉我们,这两种方法都应该被描述为“中等”,即使你可能要连续烤100个蛋糕.即使您可能需要连续处理100个慢操作,但它们之前有100个快操作,因此平均值仍然是中等。
平摊分析告诉我们,这两种方法都应该被描述为“中等”,即使你可能要连续烤100个蛋糕.即使您可能需要连续处理100个慢操作,但它们之前有100个快操作,因此平均值仍然是中等。
最坏情况是指不可能想象出更糟糕的一系列事件。例如,跳过混合面糊的操作,简单地烤100个蛋糕是没有任何意义的。这是一个缓慢的烘焙过程,但没有任何意义,所以不值得分析。蛋糕烘焙过程是一个中间过程,因为混合蛋糕糊和烘焙蛋糕有一个逻辑顺序,不能逆转。
在聚合分析中,有两个步骤。首先,我们必须证明一个序列<年代pan class="katex"> n n n业务需要<年代pan class="katex"> T ( n ) T (n) T(n)时间在最坏的情况下。然后,我们展示了每个操作所花费的时间<年代pan class="katex"> T ( n ) n n \压裂{T (n)} nT(n)时间,平均。因此,在综合分析中,每个操作的成本是相同的。在<一个t一个rget="_blank" rel="nofollow" href="#intuition">以前的举个蛋糕制作的例子,这两种操作都被描述为中操作,而不是快和慢。 聚合分析的一个常见例子是修改后的<一个href="//www.parkandroid.com/wiki/stacks/" class="wiki_link" title="堆栈gydF4y2Ba" target="_blank">堆栈.堆栈是一个<一个href="//www.parkandroid.com/wiki/linear-data-structures/" class="wiki_link" title="线性数据结构gydF4y2Ba" target="_blank">线性数据结构它有两个常数时间操作。push(元素)将一个元素放在堆栈的顶部,然后pop ()从堆栈中取出顶部元素并返回它。这些操作都是常数时间,所以总共是<年代pan class="katex"> n n n操作(以任何顺序)将导致<年代pan class="katex"> O ( n ) O (n) O(n)总时间。 现在,一个新操作被添加到堆栈中。multipop (k)会不会爆头<年代pan class="katex"> k k k堆栈中的元素,或者如果在此之前耗尽了所有元素,它将弹出堆栈中的所有元素并停止。的伪代码multipop (k)会是这样的: 1 2 3 4 Multipop (k):当堆栈不空和k > 0: k = k - 1堆栈。pop() 查看伪代码,很容易发现这不是一个常数时间的操作。multipop最多能跑一趟<年代pan class="katex"> n n n次,<年代pan class="katex"> n n n是堆栈的大小。最坏情况下的运行时间multipop是<年代pan class="katex"> O ( n ) O (n) O(n).在非典型分析中,这意味着<年代pan class="katex"> n n nmultipop业务需要<年代pan class="katex"> O ( n 2 ) 大(n ^ 2 O \ \大) O(n2)时间。 然而,事实并非如此。思考multipop以及它实际在做什么。multipop除非有一个push到堆栈,否则不能工作因为它没有东西可以弹出。事实上,任何序列<年代pan class="katex"> n n n的操作multipop,流行而且推最多能承受<年代pan class="katex"> O ( n ) O (n) O(n)时间。multipop,这个堆栈中唯一的非常量时间操作,只能取<年代pan class="katex"> O ( n ) O (n) O(n)时间若有也有<年代pan class="katex"> n n n是常量时间的推栈上的操作。在最糟糕的情况下,有<年代pan class="katex"> n n n常数时间的操作,只需要1个操作<年代pan class="katex"> O ( n ) O (n) O(n)时间。 对于任何值<年代pan class="katex"> n n n,的任意序列multipop,流行,推需要<年代pan class="katex"> O ( n ) O (n) O(n)时间。所以,通过综合分析, T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1). 所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
聚合分析的一个常见例子是修改后的<一个href="//www.parkandroid.com/wiki/stacks/" class="wiki_link" title="堆栈gydF4y2Ba" target="_blank">堆栈.堆栈是一个<一个href="//www.parkandroid.com/wiki/linear-data-structures/" class="wiki_link" title="线性数据结构gydF4y2Ba" target="_blank">线性数据结构它有两个常数时间操作。push(元素)将一个元素放在堆栈的顶部,然后pop ()从堆栈中取出顶部元素并返回它。这些操作都是常数时间,所以总共是<年代pan class="katex"> n n n操作(以任何顺序)将导致<年代pan class="katex"> O ( n ) O (n) O(n)总时间。 现在,一个新操作被添加到堆栈中。multipop (k)会不会爆头<年代pan class="katex"> k k k堆栈中的元素,或者如果在此之前耗尽了所有元素,它将弹出堆栈中的所有元素并停止。的伪代码multipop (k)会是这样的: 1 2 3 4 Multipop (k):当堆栈不空和k > 0: k = k - 1堆栈。pop() 查看伪代码,很容易发现这不是一个常数时间的操作。multipop最多能跑一趟<年代pan class="katex"> n n n次,<年代pan class="katex"> n n n是堆栈的大小。最坏情况下的运行时间multipop是<年代pan class="katex"> O ( n ) O (n) O(n).在非典型分析中,这意味着<年代pan class="katex"> n n nmultipop业务需要<年代pan class="katex"> O ( n 2 ) 大(n ^ 2 O \ \大) O(n2)时间。 然而,事实并非如此。思考multipop以及它实际在做什么。multipop除非有一个push到堆栈,否则不能工作因为它没有东西可以弹出。事实上,任何序列<年代pan class="katex"> n n n的操作multipop,流行而且推最多能承受<年代pan class="katex"> O ( n ) O (n) O(n)时间。multipop,这个堆栈中唯一的非常量时间操作,只能取<年代pan class="katex"> O ( n ) O (n) O(n)时间若有也有<年代pan class="katex"> n n n是常量时间的推栈上的操作。在最糟糕的情况下,有<年代pan class="katex"> n n n常数时间的操作,只需要1个操作<年代pan class="katex"> O ( n ) O (n) O(n)时间。 对于任何值<年代pan class="katex"> n n n,的任意序列multipop,流行,推需要<年代pan class="katex"> O ( n ) O (n) O(n)时间。所以,通过综合分析, T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1). 所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
现在,一个新操作被添加到堆栈中。multipop (k)会不会爆头<年代pan class="katex"> k k k堆栈中的元素,或者如果在此之前耗尽了所有元素,它将弹出堆栈中的所有元素并停止。的伪代码multipop (k)会是这样的: 1 2 3 4 Multipop (k):当堆栈不空和k > 0: k = k - 1堆栈。pop() 查看伪代码,很容易发现这不是一个常数时间的操作。multipop最多能跑一趟<年代pan class="katex"> n n n次,<年代pan class="katex"> n n n是堆栈的大小。最坏情况下的运行时间multipop是<年代pan class="katex"> O ( n ) O (n) O(n).在非典型分析中,这意味着<年代pan class="katex"> n n nmultipop业务需要<年代pan class="katex"> O ( n 2 ) 大(n ^ 2 O \ \大) O(n2)时间。 然而,事实并非如此。思考multipop以及它实际在做什么。multipop除非有一个push到堆栈,否则不能工作因为它没有东西可以弹出。事实上,任何序列<年代pan class="katex"> n n n的操作multipop,流行而且推最多能承受<年代pan class="katex"> O ( n ) O (n) O(n)时间。multipop,这个堆栈中唯一的非常量时间操作,只能取<年代pan class="katex"> O ( n ) O (n) O(n)时间若有也有<年代pan class="katex"> n n n是常量时间的推栈上的操作。在最糟糕的情况下,有<年代pan class="katex"> n n n常数时间的操作,只需要1个操作<年代pan class="katex"> O ( n ) O (n) O(n)时间。 对于任何值<年代pan class="katex"> n n n,的任意序列multipop,流行,推需要<年代pan class="katex"> O ( n ) O (n) O(n)时间。所以,通过综合分析, T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1). 所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
1 2 3 4
Multipop (k):当堆栈不空和k > 0: k = k - 1堆栈。pop()
查看伪代码,很容易发现这不是一个常数时间的操作。multipop最多能跑一趟<年代pan class="katex"> n n n次,<年代pan class="katex"> n n n是堆栈的大小。最坏情况下的运行时间multipop是<年代pan class="katex"> O ( n ) O (n) O(n).在非典型分析中,这意味着<年代pan class="katex"> n n nmultipop业务需要<年代pan class="katex"> O ( n 2 ) 大(n ^ 2 O \ \大) O(n2)时间。 然而,事实并非如此。思考multipop以及它实际在做什么。multipop除非有一个push到堆栈,否则不能工作因为它没有东西可以弹出。事实上,任何序列<年代pan class="katex"> n n n的操作multipop,流行而且推最多能承受<年代pan class="katex"> O ( n ) O (n) O(n)时间。multipop,这个堆栈中唯一的非常量时间操作,只能取<年代pan class="katex"> O ( n ) O (n) O(n)时间若有也有<年代pan class="katex"> n n n是常量时间的推栈上的操作。在最糟糕的情况下,有<年代pan class="katex"> n n n常数时间的操作,只需要1个操作<年代pan class="katex"> O ( n ) O (n) O(n)时间。 对于任何值<年代pan class="katex"> n n n,的任意序列multipop,流行,推需要<年代pan class="katex"> O ( n ) O (n) O(n)时间。所以,通过综合分析, T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1). 所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
multipop业务需要<年代pan class="katex"> O ( n 2 ) 大(n ^ 2 O \ \大) O(n2)时间。 然而,事实并非如此。思考multipop以及它实际在做什么。multipop除非有一个push到堆栈,否则不能工作因为它没有东西可以弹出。事实上,任何序列<年代pan class="katex"> n n n的操作multipop,流行而且推最多能承受<年代pan class="katex"> O ( n ) O (n) O(n)时间。multipop,这个堆栈中唯一的非常量时间操作,只能取<年代pan class="katex"> O ( n ) O (n) O(n)时间若有也有<年代pan class="katex"> n n n是常量时间的推栈上的操作。在最糟糕的情况下,有<年代pan class="katex"> n n n常数时间的操作,只需要1个操作<年代pan class="katex"> O ( n ) O (n) O(n)时间。 对于任何值<年代pan class="katex"> n n n,的任意序列multipop,流行,推需要<年代pan class="katex"> O ( n ) O (n) O(n)时间。所以,通过综合分析, T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1). 所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
然而,事实并非如此。思考multipop以及它实际在做什么。multipop除非有一个push到堆栈,否则不能工作因为它没有东西可以弹出。事实上,任何序列<年代pan class="katex"> n n n的操作multipop,流行而且推最多能承受<年代pan class="katex"> O ( n ) O (n) O(n)时间。multipop,这个堆栈中唯一的非常量时间操作,只能取<年代pan class="katex"> O ( n ) O (n) O(n)时间若有也有<年代pan class="katex"> n n n是常量时间的推栈上的操作。在最糟糕的情况下,有<年代pan class="katex"> n n n常数时间的操作,只需要1个操作<年代pan class="katex"> O ( n ) O (n) O(n)时间。 对于任何值<年代pan class="katex"> n n n,的任意序列multipop,流行,推需要<年代pan class="katex"> O ( n ) O (n) O(n)时间。所以,通过综合分析, T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1). 所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
对于任何值<年代pan class="katex"> n n n,的任意序列multipop,流行,推需要<年代pan class="katex"> O ( n ) O (n) O(n)时间。所以,通过综合分析, T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1). 所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
T ( n ) n = O ( n ) n = O ( 1 ) . \frac{T(n)}{n} = \frac{O(n)}{n} = O(1)。 nT(n)=nO(n)=O(1).
所以这一叠的平摊代价是<年代pan class="katex"> O ( 1 ) O (1) O(1)每个操作。
会计方法的命名很恰当,因为它借鉴了会计的概念和术语。在这里,每个操作都分配一个费用,称为<年代trong>摊余成本.有些操作的收费可能比实际成本高或低。如果一个操作的平摊代价超过了它的实际代价,我们将其差值赋值为a<年代trong>信贷,指向数据结构中的特定对象。信用日后可以用来帮助支付摊销成本低于实际成本的其他业务。在任何操作序列中,信用都不可能是负的。 一项业务的摊余成本是在业务的实际成本和存入或用完的信贷之间分割的。每一个操作都有不同的平摊代价<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.为每个操作选择平摊代价是很重要的,但对于给定的操作,无论操作的顺序是什么,其代价必须总是相同的,就像平摊分析的任何方法一样。 回顾上一节修改的堆栈,每个操作的成本为 1 2 3 Push: 1 Pop: 1 Multipop: min(堆叠。大小、k) Multipop的成本将会是<年代pan class="katex"> k k k如果<年代pan class="katex"> k k k小于堆栈中的元素数量,否则将等于堆栈的大小。给这些函数分配平摊代价,我们得到 1 2 3 Push: 2 Pop: 0 Multipop: 0 这里值得注意的是,多重pop的平摊成本是恒定的,而它的实际成本是可变的。 最后一步是要证明它是可以付费的任何使用平摊代价的一系列操作。用金钱来完成这个步骤是有帮助的,所以1美元等于1成本。 如果我们把这堆盘子想象成真正的一堆盘子,这就更清楚了。把一个盘子推到堆栈上的行为就是把那个盘子放在堆栈的顶部。掰开就是把上面的盘子掰开。所以,在这个例子中,当一个盘子被推到堆栈上时,我们为操作的实际成本支付1美元,我们还剩下1美元的信贷。这是因为我们用推送的平摊代价(2美元)减去实际代价(1美元),剩下1美元。我们把那美元放在刚推的盘子上。所以,在任何时间点,叠里的每个盘子都有1美元的存款。 盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
一项业务的摊余成本是在业务的实际成本和存入或用完的信贷之间分割的。每一个操作都有不同的平摊代价<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.为每个操作选择平摊代价是很重要的,但对于给定的操作,无论操作的顺序是什么,其代价必须总是相同的,就像平摊分析的任何方法一样。 回顾上一节修改的堆栈,每个操作的成本为 1 2 3 Push: 1 Pop: 1 Multipop: min(堆叠。大小、k) Multipop的成本将会是<年代pan class="katex"> k k k如果<年代pan class="katex"> k k k小于堆栈中的元素数量,否则将等于堆栈的大小。给这些函数分配平摊代价,我们得到 1 2 3 Push: 2 Pop: 0 Multipop: 0 这里值得注意的是,多重pop的平摊成本是恒定的,而它的实际成本是可变的。 最后一步是要证明它是可以付费的任何使用平摊代价的一系列操作。用金钱来完成这个步骤是有帮助的,所以1美元等于1成本。 如果我们把这堆盘子想象成真正的一堆盘子,这就更清楚了。把一个盘子推到堆栈上的行为就是把那个盘子放在堆栈的顶部。掰开就是把上面的盘子掰开。所以,在这个例子中,当一个盘子被推到堆栈上时,我们为操作的实际成本支付1美元,我们还剩下1美元的信贷。这是因为我们用推送的平摊代价(2美元)减去实际代价(1美元),剩下1美元。我们把那美元放在刚推的盘子上。所以,在任何时间点,叠里的每个盘子都有1美元的存款。 盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
回顾上一节修改的堆栈,每个操作的成本为 1 2 3 Push: 1 Pop: 1 Multipop: min(堆叠。大小、k) Multipop的成本将会是<年代pan class="katex"> k k k如果<年代pan class="katex"> k k k小于堆栈中的元素数量,否则将等于堆栈的大小。给这些函数分配平摊代价,我们得到 1 2 3 Push: 2 Pop: 0 Multipop: 0 这里值得注意的是,多重pop的平摊成本是恒定的,而它的实际成本是可变的。 最后一步是要证明它是可以付费的任何使用平摊代价的一系列操作。用金钱来完成这个步骤是有帮助的,所以1美元等于1成本。 如果我们把这堆盘子想象成真正的一堆盘子,这就更清楚了。把一个盘子推到堆栈上的行为就是把那个盘子放在堆栈的顶部。掰开就是把上面的盘子掰开。所以,在这个例子中,当一个盘子被推到堆栈上时,我们为操作的实际成本支付1美元,我们还剩下1美元的信贷。这是因为我们用推送的平摊代价(2美元)减去实际代价(1美元),剩下1美元。我们把那美元放在刚推的盘子上。所以,在任何时间点,叠里的每个盘子都有1美元的存款。 盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
1 2 3
Push: 1 Pop: 1 Multipop: min(堆叠。大小、k)
Multipop的成本将会是<年代pan class="katex"> k k k如果<年代pan class="katex"> k k k小于堆栈中的元素数量,否则将等于堆栈的大小。给这些函数分配平摊代价,我们得到 1 2 3 Push: 2 Pop: 0 Multipop: 0 这里值得注意的是,多重pop的平摊成本是恒定的,而它的实际成本是可变的。 最后一步是要证明它是可以付费的任何使用平摊代价的一系列操作。用金钱来完成这个步骤是有帮助的,所以1美元等于1成本。 如果我们把这堆盘子想象成真正的一堆盘子,这就更清楚了。把一个盘子推到堆栈上的行为就是把那个盘子放在堆栈的顶部。掰开就是把上面的盘子掰开。所以,在这个例子中,当一个盘子被推到堆栈上时,我们为操作的实际成本支付1美元,我们还剩下1美元的信贷。这是因为我们用推送的平摊代价(2美元)减去实际代价(1美元),剩下1美元。我们把那美元放在刚推的盘子上。所以,在任何时间点,叠里的每个盘子都有1美元的存款。 盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
Push: 2 Pop: 0 Multipop: 0
这里值得注意的是,多重pop的平摊成本是恒定的,而它的实际成本是可变的。 最后一步是要证明它是可以付费的任何使用平摊代价的一系列操作。用金钱来完成这个步骤是有帮助的,所以1美元等于1成本。 如果我们把这堆盘子想象成真正的一堆盘子,这就更清楚了。把一个盘子推到堆栈上的行为就是把那个盘子放在堆栈的顶部。掰开就是把上面的盘子掰开。所以,在这个例子中,当一个盘子被推到堆栈上时,我们为操作的实际成本支付1美元,我们还剩下1美元的信贷。这是因为我们用推送的平摊代价(2美元)减去实际代价(1美元),剩下1美元。我们把那美元放在刚推的盘子上。所以,在任何时间点,叠里的每个盘子都有1美元的存款。 盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
最后一步是要证明它是可以付费的任何使用平摊代价的一系列操作。用金钱来完成这个步骤是有帮助的,所以1美元等于1成本。 如果我们把这堆盘子想象成真正的一堆盘子,这就更清楚了。把一个盘子推到堆栈上的行为就是把那个盘子放在堆栈的顶部。掰开就是把上面的盘子掰开。所以,在这个例子中,当一个盘子被推到堆栈上时,我们为操作的实际成本支付1美元,我们还剩下1美元的信贷。这是因为我们用推送的平摊代价(2美元)减去实际代价(1美元),剩下1美元。我们把那美元放在刚推的盘子上。所以,在任何时间点,叠里的每个盘子都有1美元的存款。 盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
如果我们把这堆盘子想象成真正的一堆盘子,这就更清楚了。把一个盘子推到堆栈上的行为就是把那个盘子放在堆栈的顶部。掰开就是把上面的盘子掰开。所以,在这个例子中,当一个盘子被推到堆栈上时,我们为操作的实际成本支付1美元,我们还剩下1美元的信贷。这是因为我们用推送的平摊代价(2美元)减去实际代价(1美元),剩下1美元。我们把那美元放在刚推的盘子上。所以,在任何时间点,叠里的每个盘子都有1美元的存款。 盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
盘子上面的1美元将作为打开盘子所需的钱。我们需要1美元来取出盘子因为取出盘子的平摊代价(0美元)减去取出盘子的实际代价(1美元)等于- 1美元。在任何时候,每个盘子上面都有1美元,可以用来把盘子从盘子里取出来。 Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
Multipop使用pop作为子程序。在堆栈上调用multipop不需要花钱,但是multipop中的pop子例程将使用每个盘子顶部的1美元来删除它。 因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
因为每一个盘子上面都有1美元,所以信用永远不会是负的。从本质上讲,这和我们之前探讨的想法是一样的<一个t一个rget="_blank" rel="nofollow" href="#aggregate-analysis">聚合分析.执行pop或multipop没有任何意义,直到有东西被推送到堆栈。没有什么好弹的!最坏情况的代价是<年代pan class="katex"> n n n操作<年代pan class="katex"> O ( n ) O (n) O(n).
电位法类似于会计方法。然而,潜在的方法不是考虑成本和信用的分析,而是考虑已经完成的工作<年代trong>势能可以支付以后的手术费用。这类似于把石头推上山产生的势能,然后可以毫不费力地把它带下山。然而,与计算方法不同的是,势能与数据结构作为一个整体相关联,而不是与单个操作相关联。 势能方法的工作原理如下:它从一个初始数据结构开始,<年代pan class="katex"> D 0 数 D0.然后<年代pan class="katex"> n n n执行操作,将初始数据结构转换为<年代pan class="katex"> D 1 , D 2 , D 3. , . . . , D n D_1, d_2, d_3,…, D_n D1,D2,D3.,...,Dn.<年代pan class="katex"> c 我 为c_i c我会不会与成本相关<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作,<年代pan class="katex"> D 我 d1 D我数据结构是由<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作。 Φ \φ Φ是<年代trong>势函数哪个映射了数据结构<年代pan class="katex"> D D D许多<年代pan class="katex"> Φ ( D ) \φ(D) Φ(D),与该数据结构相关联的潜力。的<年代trong>摊余成本的<年代pan class="katex"> 我 我 我操作定义为 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) . a_i = c_i + \Phi(D_i) - \Phi(D_{i-1})。 一个我=c我+Φ(D我)−Φ(D我−1). 这意味着结束<年代pan class="katex"> n n n总的平摊代价将是 ∑ 我 = 1 n 一个 我 = ∑ 我 = 1 n ( c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) ) . \ sum_ {i = 1} ^ = {n} a_i \ sum_ {i = 1} ^ {n} \大(为c_i + \φ(d1) - \φ(D_张{})\大)。 我=1∑n一个我=我=1∑n(c我+Φ(D我)−Φ(D我−1)). 因为这是<一个href="//www.parkandroid.com/wiki/telescoping-series/" class="wiki_link" title="可伸缩的总和gydF4y2Ba" target="_blank">可伸缩的总和,它等于 ∑ 我 = 1 n c 我 + Φ ( D n ) − Φ ( D 0 ) . \sum_{i=1}^{n}c_i + \Phi(D_n) - \Phi(D_0)。 我=1∑nc我+Φ(Dn)−Φ(D0). 在这个方法中,它是要求那<年代pan class="katex"> Φ ( D 我 ) ≥ Φ ( D 0 ) \φ(d1) \组\φ(数) Φ(D我)≥Φ(D0)对所有<年代pan class="katex"> 我 我 我证明了总平摊代价为<年代pan class="katex"> n n n操作是实际总成本的上界。一种典型的方法是定义<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0并显示<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0. 在一系列操作的过程中<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作时会有电势差<年代pan class="katex"> Φ ( D 我 ) − Φ ( D 我 − 1 ) \φ(d1) - \φ(D_张{}) Φ(D我)−Φ(D我−1).如果这个值是正的,那么平摊代价<年代pan class="katex"> 一个 我 ai 一个我对于这个操作是一个过充,并且数据结构的势能会增加。如果是负的,则为欠电荷,数据结构的势能会降低。 让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
势能方法的工作原理如下:它从一个初始数据结构开始,<年代pan class="katex"> D 0 数 D0.然后<年代pan class="katex"> n n n执行操作,将初始数据结构转换为<年代pan class="katex"> D 1 , D 2 , D 3. , . . . , D n D_1, d_2, d_3,…, D_n D1,D2,D3.,...,Dn.<年代pan class="katex"> c 我 为c_i c我会不会与成本相关<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作,<年代pan class="katex"> D 我 d1 D我数据结构是由<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作。 Φ \φ Φ是<年代trong>势函数哪个映射了数据结构<年代pan class="katex"> D D D许多<年代pan class="katex"> Φ ( D ) \φ(D) Φ(D),与该数据结构相关联的潜力。的<年代trong>摊余成本的<年代pan class="katex"> 我 我 我操作定义为 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) . a_i = c_i + \Phi(D_i) - \Phi(D_{i-1})。 一个我=c我+Φ(D我)−Φ(D我−1). 这意味着结束<年代pan class="katex"> n n n总的平摊代价将是 ∑ 我 = 1 n 一个 我 = ∑ 我 = 1 n ( c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) ) . \ sum_ {i = 1} ^ = {n} a_i \ sum_ {i = 1} ^ {n} \大(为c_i + \φ(d1) - \φ(D_张{})\大)。 我=1∑n一个我=我=1∑n(c我+Φ(D我)−Φ(D我−1)). 因为这是<一个href="//www.parkandroid.com/wiki/telescoping-series/" class="wiki_link" title="可伸缩的总和gydF4y2Ba" target="_blank">可伸缩的总和,它等于 ∑ 我 = 1 n c 我 + Φ ( D n ) − Φ ( D 0 ) . \sum_{i=1}^{n}c_i + \Phi(D_n) - \Phi(D_0)。 我=1∑nc我+Φ(Dn)−Φ(D0). 在这个方法中,它是要求那<年代pan class="katex"> Φ ( D 我 ) ≥ Φ ( D 0 ) \φ(d1) \组\φ(数) Φ(D我)≥Φ(D0)对所有<年代pan class="katex"> 我 我 我证明了总平摊代价为<年代pan class="katex"> n n n操作是实际总成本的上界。一种典型的方法是定义<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0并显示<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0. 在一系列操作的过程中<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作时会有电势差<年代pan class="katex"> Φ ( D 我 ) − Φ ( D 我 − 1 ) \φ(d1) - \φ(D_张{}) Φ(D我)−Φ(D我−1).如果这个值是正的,那么平摊代价<年代pan class="katex"> 一个 我 ai 一个我对于这个操作是一个过充,并且数据结构的势能会增加。如果是负的,则为欠电荷,数据结构的势能会降低。 让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
Φ \φ Φ是<年代trong>势函数哪个映射了数据结构<年代pan class="katex"> D D D许多<年代pan class="katex"> Φ ( D ) \φ(D) Φ(D),与该数据结构相关联的潜力。的<年代trong>摊余成本的<年代pan class="katex"> 我 我 我操作定义为 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) . a_i = c_i + \Phi(D_i) - \Phi(D_{i-1})。 一个我=c我+Φ(D我)−Φ(D我−1). 这意味着结束<年代pan class="katex"> n n n总的平摊代价将是 ∑ 我 = 1 n 一个 我 = ∑ 我 = 1 n ( c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) ) . \ sum_ {i = 1} ^ = {n} a_i \ sum_ {i = 1} ^ {n} \大(为c_i + \φ(d1) - \φ(D_张{})\大)。 我=1∑n一个我=我=1∑n(c我+Φ(D我)−Φ(D我−1)). 因为这是<一个href="//www.parkandroid.com/wiki/telescoping-series/" class="wiki_link" title="可伸缩的总和gydF4y2Ba" target="_blank">可伸缩的总和,它等于 ∑ 我 = 1 n c 我 + Φ ( D n ) − Φ ( D 0 ) . \sum_{i=1}^{n}c_i + \Phi(D_n) - \Phi(D_0)。 我=1∑nc我+Φ(Dn)−Φ(D0). 在这个方法中,它是要求那<年代pan class="katex"> Φ ( D 我 ) ≥ Φ ( D 0 ) \φ(d1) \组\φ(数) Φ(D我)≥Φ(D0)对所有<年代pan class="katex"> 我 我 我证明了总平摊代价为<年代pan class="katex"> n n n操作是实际总成本的上界。一种典型的方法是定义<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0并显示<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0. 在一系列操作的过程中<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作时会有电势差<年代pan class="katex"> Φ ( D 我 ) − Φ ( D 我 − 1 ) \φ(d1) - \φ(D_张{}) Φ(D我)−Φ(D我−1).如果这个值是正的,那么平摊代价<年代pan class="katex"> 一个 我 ai 一个我对于这个操作是一个过充,并且数据结构的势能会增加。如果是负的,则为欠电荷,数据结构的势能会降低。 让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) . a_i = c_i + \Phi(D_i) - \Phi(D_{i-1})。 一个我=c我+Φ(D我)−Φ(D我−1).
这意味着结束<年代pan class="katex"> n n n总的平摊代价将是 ∑ 我 = 1 n 一个 我 = ∑ 我 = 1 n ( c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) ) . \ sum_ {i = 1} ^ = {n} a_i \ sum_ {i = 1} ^ {n} \大(为c_i + \φ(d1) - \φ(D_张{})\大)。 我=1∑n一个我=我=1∑n(c我+Φ(D我)−Φ(D我−1)). 因为这是<一个href="//www.parkandroid.com/wiki/telescoping-series/" class="wiki_link" title="可伸缩的总和gydF4y2Ba" target="_blank">可伸缩的总和,它等于 ∑ 我 = 1 n c 我 + Φ ( D n ) − Φ ( D 0 ) . \sum_{i=1}^{n}c_i + \Phi(D_n) - \Phi(D_0)。 我=1∑nc我+Φ(Dn)−Φ(D0). 在这个方法中,它是要求那<年代pan class="katex"> Φ ( D 我 ) ≥ Φ ( D 0 ) \φ(d1) \组\φ(数) Φ(D我)≥Φ(D0)对所有<年代pan class="katex"> 我 我 我证明了总平摊代价为<年代pan class="katex"> n n n操作是实际总成本的上界。一种典型的方法是定义<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0并显示<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0. 在一系列操作的过程中<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作时会有电势差<年代pan class="katex"> Φ ( D 我 ) − Φ ( D 我 − 1 ) \φ(d1) - \φ(D_张{}) Φ(D我)−Φ(D我−1).如果这个值是正的,那么平摊代价<年代pan class="katex"> 一个 我 ai 一个我对于这个操作是一个过充,并且数据结构的势能会增加。如果是负的,则为欠电荷,数据结构的势能会降低。 让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
∑ 我 = 1 n 一个 我 = ∑ 我 = 1 n ( c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) ) . \ sum_ {i = 1} ^ = {n} a_i \ sum_ {i = 1} ^ {n} \大(为c_i + \φ(d1) - \φ(D_张{})\大)。 我=1∑n一个我=我=1∑n(c我+Φ(D我)−Φ(D我−1)).
因为这是<一个href="//www.parkandroid.com/wiki/telescoping-series/" class="wiki_link" title="可伸缩的总和gydF4y2Ba" target="_blank">可伸缩的总和,它等于 ∑ 我 = 1 n c 我 + Φ ( D n ) − Φ ( D 0 ) . \sum_{i=1}^{n}c_i + \Phi(D_n) - \Phi(D_0)。 我=1∑nc我+Φ(Dn)−Φ(D0). 在这个方法中,它是要求那<年代pan class="katex"> Φ ( D 我 ) ≥ Φ ( D 0 ) \φ(d1) \组\φ(数) Φ(D我)≥Φ(D0)对所有<年代pan class="katex"> 我 我 我证明了总平摊代价为<年代pan class="katex"> n n n操作是实际总成本的上界。一种典型的方法是定义<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0并显示<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0. 在一系列操作的过程中<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作时会有电势差<年代pan class="katex"> Φ ( D 我 ) − Φ ( D 我 − 1 ) \φ(d1) - \φ(D_张{}) Φ(D我)−Φ(D我−1).如果这个值是正的,那么平摊代价<年代pan class="katex"> 一个 我 ai 一个我对于这个操作是一个过充,并且数据结构的势能会增加。如果是负的,则为欠电荷,数据结构的势能会降低。 让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
∑ 我 = 1 n c 我 + Φ ( D n ) − Φ ( D 0 ) . \sum_{i=1}^{n}c_i + \Phi(D_n) - \Phi(D_0)。 我=1∑nc我+Φ(Dn)−Φ(D0).
在这个方法中,它是要求那<年代pan class="katex"> Φ ( D 我 ) ≥ Φ ( D 0 ) \φ(d1) \组\φ(数) Φ(D我)≥Φ(D0)对所有<年代pan class="katex"> 我 我 我证明了总平摊代价为<年代pan class="katex"> n n n操作是实际总成本的上界。一种典型的方法是定义<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0并显示<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0. 在一系列操作的过程中<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作时会有电势差<年代pan class="katex"> Φ ( D 我 ) − Φ ( D 我 − 1 ) \φ(d1) - \φ(D_张{}) Φ(D我)−Φ(D我−1).如果这个值是正的,那么平摊代价<年代pan class="katex"> 一个 我 ai 一个我对于这个操作是一个过充,并且数据结构的势能会增加。如果是负的,则为欠电荷,数据结构的势能会降低。 让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
在一系列操作的过程中<年代pan class="katex"> 我 th 我^ \文本{th} 我th操作时会有电势差<年代pan class="katex"> Φ ( D 我 ) − Φ ( D 我 − 1 ) \φ(d1) - \φ(D_张{}) Φ(D我)−Φ(D我−1).如果这个值是正的,那么平摊代价<年代pan class="katex"> 一个 我 ai 一个我对于这个操作是一个过充,并且数据结构的势能会增加。如果是负的,则为欠电荷,数据结构的势能会降低。 让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
让我们回头看看修改后的堆栈。选择的潜在函数将仅仅是堆栈上项目的数量。因此,在一系列操作开始之前,<年代pan class="katex"> Φ ( D 0 ) = 0 \φ(数)= 0 Φ(D0)=0因为堆栈中没有项目。对于未来的所有行动,很明显<年代pan class="katex"> Φ ( D 我 ) ≥ 0 \φ(d1) \组0 Φ(D我)≥0因为堆栈中不可能有负数的项。 计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
计算推操作的电位差,我们发现 Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1. 推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
Φ ( D 我 ) − Φ ( D 我 − 1 ) = ( 年代 t 一个 c k . 年代 我 z e + 1 ) − 年代 t 一个 c k . 年代 我 z e = 1. \Phi(D_{i-1}) =(堆栈;大小+ 1)-堆叠。大小= 1。 Φ(D我)−Φ(D我−1)=(年代t一个ck.年代我ze+1)−年代t一个ck.年代我ze=1.
推操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2. 流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 1 + 1 = 2. ai =为c_i + \φ(d1) - \φ(D_张{})= 1 + 1 = 2。 一个我=c我+Φ(D我)−Φ(D我−1)=1+1=2.
流行音乐和多流行音乐的潜在区别是什么?流行音乐和多重流行音乐的平摊成本是多少? 显示答案 计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
计算pop和multipop的平摊成本是相似的,所以这里只显示multipop。参数为的多弹出操作的电位差<年代pan class="katex"> k k k是 Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k). 那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
Φ ( D 我 ) − Φ ( D 我 − 1 ) = − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) . \Phi(D_{i-1}) = -\min(堆栈;大小,k)。 Φ(D我)−Φ(D我−1)=−最小值(年代t一个ck.年代我ze,k).
那么,多重取出操作的平摊代价是 一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =
一个 我 = c 我 + Φ ( D 我 ) − Φ ( D 我 − 1 ) = 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) + ( − 最小值 ( 年代 t 一个 c k . 年代 我 z e , k ) ) =