Algorithm 这个关于动态数组大小调整的公式是如何实现的?

Algorithm 这个关于动态数组大小调整的公式是如何实现的?,algorithm,Algorithm,我还将此发布到mathematics.stackexchange和theoreticalcomputerscience.stackexchange。但我不确定它是否更适合这个论坛 我正在阅读斯基纳的《算法设计手册》 他分析了在动态数组中执行的复制操作的数量 “假设我们从一个大小为1的数组开始,每次用完空间时,将其大小从m加倍到2m。此加倍过程涉及分配一个大小为2m的新连续数组,将旧数组的内容复制到新数组的下半部分。表面上的浪费是在每次膨胀时重新包装旧内容物 斯基纳接着问道: “一个元素在总共插入

我还将此发布到mathematics.stackexchange和theoreticalcomputerscience.stackexchange。但我不确定它是否更适合这个论坛

我正在阅读斯基纳的《算法设计手册》

他分析了在动态数组中执行的复制操作的数量

“假设我们从一个大小为1的数组开始,每次用完空间时,将其大小从
m
加倍到
2m
。此加倍过程涉及分配一个大小为
2m
的新连续数组,将旧数组的内容复制到新数组的下半部分。表面上的浪费是在每次膨胀时重新包装旧内容物

斯基纳接着问道:

“一个元素在总共插入
n
之后需要重新编译多少次?”

然后,他给出了一个公式,用于计算插入
n
的移动总数
M

他的解释是:

“嗯,当数组在第一次、第二次、第四次、第八次……插入后展开时,第一个插入的元素将被重新复制。需要加倍,直到数组有n个位置。然而,大多数元素并没有遭受太大的动荡。事实上,st到
n
th元素最多移动一次,可能根本不需要移动。”


但我真的不明白他是如何从中得出这个公式的。有人能帮我理解他是如何得出这个公式的吗?主要是我不明白的是,他为什么要乘以
I

这是说n/2个元素最多只能复制一次(正如你正确推断的那样)。此外,n/4个元素被复制两次。n/8个元素被复制3次,依此类推。

它表示副本的数量。让我们做一个简单的例子。按以下顺序进行插入

[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]

元素
16
使数组加倍(因为它变得大于
2^4

让我们计算副本:

15,14,13,12,11,10,9,8 were copied just once (i=1) * (n/2^i)
7,6,5,4               were copied twice (i=2)
3,2                   were copied three times (i=3)
1                     was copied 4 times (i=4)
0                     was copied 5 times (i=5)

因此,我假设,对于上界,它应该是总和极限中的
ceil(logn)
,总和中的
ceil(n/2^I)
,但无论如何,这应该回答
I
从何而来的问题。

他在讲座第52分钟左右解释道:

此处M表示包含项目初始化的移动。最后n/2个项目移动一次,但从未复制

但是我发现M=15表示n=8[第一个元素4次+2次3次+3次2次+4次2次+5次1次+6次1次+7次1次+8次1]。公式应该是M=(求和表达式)+lg(n)+1=O(n)(仍然)。第一个元素被复制lg(n)次,因此它被移动lg(n)+1次用于实例化