1

假设您使用一个数组实现了一个堆,并且每次数组已满时,您将其复制到一个大小为两倍的数组中。将元素插入堆的摊销时间复杂度(最坏情况下)是多少?

我认为我们有T(n) = n * n(这是在最坏情况下一系列 n 操作的总成本的上限),然后根据一个公式的摊销复杂度是T(n) / n = n^n / n = n

但是我认为这是非常错误的,因为直觉很清楚我应该得到log(n)或更低......那么我应该如何计算呢?

4

1 回答 1

2

想象一下,您将 n 个元素插入以这种方式表示的堆中。您需要考虑两种不同的成本来源:

  1. 堆操作的成本,忽略底层数组调整大小。
  2. 数组调整大小的成本,忽略了总体堆操作。

(1) 的成本在 n 个总操作中是 O(n log n),因为每个堆插入需要时间 O(log n)。

对于 (2) 的成本,请注意将数组大小加倍所做的工作与数组加倍时的大小成正比。这意味着您将执行 1 个工作单元将数组的大小从 1 翻倍,将 2 个工作单元将数组的大小从 2 翻倍,将 4 个工作单元将数组的大小从 4 翻倍,等等。这意味着总完成的工作是

1 + 2 + 4 + 8 + 16 + ... + 2 1 + log n ≤ 4n - 1 = O(n)

这个数学使用了这样一个事实,即在数组达到大小 n 之前,您最多只能将数组加倍 1 + log n 次,并且 1 + 2 + 4 + 8 + ... + 2 k = 2 k+1 - 1。这个意味着在所有 n 次插入中,您所做的 O(n) 工作将数组加倍。

总体而言,跨 n 次操作完成的总工作量为 O(n log n),因此每次操作的摊销成本为 O(log n)。

于 2016-06-13T20:36:08.857 回答