当前位置: 首页 > 面试题库 >

为什么ArrayList的add()和add(int index,E)复杂度要按固定时间摊销?为什么不为add()设置O(1),为add(intindex,E)设置O(n)?

公冶嘉茂
2023-03-14
问题内容

为什么ArrayList的add()和add(int index,E)复杂度要按固定时间摊销?

为什么不对单个add()操作使用O(1),对单个add(int索引,E)操作使用O(n),而对于使用任一(任何)添加方法添加n个元素(n个添加操作)的O(n)呢?假设我们很少使用add(int
index,E)添加到数组末尾?

数组(和ArrayList)的操作复杂度已经不是n个元素了:

  1. add()-O(1)?
  2. add(int index,E)-O(n)?

如果我们插入一百万次,则平均值1和2不能为O(1),对吗?

为什么甲骨文说

加法运算以 固定的固定时间 运行,也就是说, 添加n个元素需要O(n)时间

我认为add()的复杂度为O(1),add(int index,E)的复杂度为O(n)。

这是否意味着“ n个操作的积分复杂度”(每个操作的复杂度为O(1))可以说n * O(1)= O(n)。我想念什么?

也许对于Oracle“添加操作”总是意味着仅add()?而add(int,E)是“插入操作”吗?然后完全清除!

我有一个猜测,这与 渐进分析摊销分析 之间的差异有关,但我无法掌握到最后。

什么是算法的摊销分析?


问题答案:

用Oracle的术语(默示的)和谈论List

  • 添加方法 ”(同义词-“ 附加方法 ”)始终表示boolean add(E)
  • 插入方法 ”总是意味着boolean add(int index, E)

当Oracle写的时候

加法运算以固定的固定时间运行,也就是说,添加n个元素需要O(n)时间。

它的意思是:

单个boolean add(E)操作的复杂度以O(1)摊销。

它不能只是(总是)渐近的O(1),因为很少需要增加阵列容量。实际上,此单个添加操作是“创建新的更大的数组,将旧的数组复制到其中,然后将一个元素添加到末尾”操作,其渐近复杂度为O(n),因为在增加List容量时复制数组为O(
n),增长加法的复杂度为O(n)[计算为O(n)+ O(1)=
O(n)]。如果没有这种容量增长操作,则添加复杂度将为O(1),元素总是添加(附加)到数组的末尾(最大索引)。如果我们不向数组末尾“添加”(=插入),则需要移动最右边的元素(具有更大的索引),并且单个此类操作的复杂度将为O(n)。

现在,对于单个加法运算,渐进复杂度为O(1)表示不增加容量,而O(n)表示不增加容量(这种情况很少发生)。

单个加法运算的摊余复杂度为O(1)。它反映了一个事实,即稀有的O(n)增长与添加操作会被大量的O(1)无增长操作“稀释”,因此“平均”的单个操作为O(1)。

n个加法运算的“渐近复杂度”为O(n)。但是在这里,我们谈论的是n个运算的复杂度,而不是一个运算的复杂度。这不是严格的表达方式(“渐进复杂性”),但无论如何。n次操作的摊销复杂度甚至没有意义。

最后,boolean add(int index, E)单个操作的复杂度始终为O(n)。如果触发增长,则为O(n)+ O(n)[增长+插入],但2 * O(n)与O(n)相同。



 类似资料:
  • 问题内容: 从链接列表标签Wiki摘录: 链表是一种数据结构,其中的元素包含对下一个(以及可选的上一个)元素的引用。链接列表可 在任何位置 提供 O(1)插入和删除 ,O(1)列表串联,以及在前(和可选)后位置的O(1)访问以及对下一个元素的O(1)访问。随机访问具有O(N)的复杂度,通常没有实现。 (强调我的) 令我惊讶的是,该列表如何以比简单 读取 该索引低的复杂度 插入 一个随机索引? __

  • 我不明白堆排序的空间复杂度是怎样的O(1)?虽然快速排序不使用任何额外的数组(即就地),但在最坏情况下其空间复杂度为O(n),在最佳情况下为O(lg n),因为在递归调用的后端使用堆栈。我说得对吗? 堆排序也是如此。虽然,它是就地的,但是由于Build-Heap函数调用Max-Heapify函数,所以它的空间复杂度应该等于Max-Heapify,即O(lg n)。不是吗?此外,稍后在根节点调用Ma

  • 问题内容: 从TimeComplexity文档中可以看出,Python的类型是使用数组实现的。 因此,如果正在使用数组并且进行了一些附加操作,最终您将不得不重新分配空间并将所有信息复制到新空间。 毕竟,这是O(1)最坏的情况吗? 问题答案: 如果查看链接文档中的脚注,您会发现它们包含一个警告: 这些操作依赖于“最坏情况摊销”的“摊销”部分。根据容器的历史记录,各个动作可能会花费惊人的时间。 使用摊

  • 我的老师给了我一个我正在写的方法的这个类比。我还是不明白为什么add方法会返回一个boolean?

  • 问题内容: 我刚刚开始学习数据结构,并且在进行数组插入时想知道为什么数组插入的时间复杂度为O(n)而不是O(n + 1)? 在最佳情况下,当插入在最后时,时间复杂度为O(1)。我想我们正在考虑1插入元素,因为这里没有元素被移动。在最坏的情况下,假设我们必须移动n个元素然后插入新元素,那么时间时间复杂度是否应该为O(n + 1)?n用于移动元素,1用于插入。 非常感谢您的帮助。 问题答案: O(n)

  • 问题内容: 整数有一个方法: …但是调用它会引发SyntaxError: 为什么不能使用该方法? 问题答案: 被解析为浮点数,SyntaxError也被解析。 您可以评估 代替。