Data structures 堆栈动态数组实现的复杂性

Data structures 堆栈动态数组实现的复杂性,data-structures,stack,complexity-theory,Data Structures,Stack,Complexity Theory,在典型的动态数组实现中,当没有空间容纳新元素时,我们会将堆栈加倍。在这种情况下,推送操作的平均时间加倍为O(n) 如果我们没有加倍,而是将堆栈大小增加了(n+k)? 我的做法如下 假设堆栈为空,k=10,我们将堆栈增加到10个元素。在10个元素之后,我们将其设为20个元素,以此类推 复制周围元素的平均时间为10+20+30+ 那么推送的平均时间必须是O(n)的顺序 我的方法正确吗?取决于如何增加存储空间,并且k足够小,对于所有情况或其他情况,它可能是O(1) 我的意思是,在托管语言中,可以创建一

在典型的动态数组实现中,当没有空间容纳新元素时,我们会将堆栈加倍。在这种情况下,推送操作的平均时间加倍为O(n)

如果我们没有加倍,而是将堆栈大小增加了(n+k)?

我的做法如下

假设堆栈为空,k=10,我们将堆栈增加到10个元素。在10个元素之后,我们将其设为20个元素,以此类推

复制周围元素的平均时间为10+20+30+

那么推送的平均时间必须是O(n)的顺序


我的方法正确吗?

取决于如何增加存储空间,并且k足够小,对于所有情况或其他情况,它可能是O(1)

我的意思是,在托管语言中,可以创建一个大小为n+k的新数组,然后将旧数组(大小为n)复制到新数组,最后将旧数组的引用替换为新数组。这将是:O(1)(数组创建,这是一个假设)+O(n)(数据拷贝)+O(1)(引用更改)。我们忽略垃圾收集器的执行,因为它非常依赖于实现。在非托管语言中,可以使用类似于
realloc
的东西,以便保留旧元素而无需复制,因为新存储占用相同的内存区域,仅扩展到所需的项目数。在这种情况下,所有情况下都是O(1)。但是,请注意,有时由于内存碎片的原因,无法将存储扩展到所需的项目数,因此采用了类似于托管语言的方法(但通过
realloc
实现隐式实现)。对于这个,复杂性与托管语言中的复杂性相同:O(n)


这是从实践的角度给出的答案,我希望你能用上面的答案从分析的角度找到答案。祝你好运。

你的计算不正确。动态数组的典型实现将其大小加倍(或者更一般地说,将其大小增加x%)是有原因的

如果将大小从1增加到n=2i,则复制的元素总数为1+2+4+8+16+…+2i。如果求和,它小于2i+1,因此总时间复杂度为O(n),一次插入的时间复杂度为O(1)。如果n不是2的幂,计算会稍微复杂一些,但结果是一样的

另一方面,如果将大小增加k,从0增加到n=i*k,则复制的元素总数为k+2k+3k+…+ik。如果将其相加,则为(ik+k)*(ik/k)/2=O(n2)。一次插入的摊销复杂度为O(n)

因此,您的解决方案比将大小加倍要糟糕得多