为什么在动态数组O(n)时间复杂度结束时删除项目?

时间:2018-12-27 04:23:22

标签: java dynamic-arrays

我目前正在阅读教科书,我完全困惑为什么动态数组需要O(n)时间才能删除最后一个项目。我知道从任何其他索引中删除一项都是O(n),因为您必须复制所有数据并移动它们以填补空白,但是如果最后,我们不只是减少计数并设置索引是0还是null?我包括了我书中的一张照片。这很奇怪,因为它说索引为O(1),所以我们必须知道项目在哪里,所以我们不必像链接列表一样遍历数组。enter image description here

7 个答案:

答案 0 :(得分:15)

首先,让我们看一下“动态数组”这些书的含义:

  

动态数组(也称为可增长数组可调整大小的数组,   动态表数组列表)是一种随机访问的,可变大小的列表数据结构,允许添加或删除元素。   [...]
  注意:我们将在堆栈,队列和散列章节中看到动态数组的实现。

由此我们得知,数组列表是本书作者定义的“动态数组”的示例。

但进一步看,这本书提到:

  

该数组填满后,立即创建大小为新的数组   是原始数组的两倍。同样,将数组大小减小为   如果数组中的元素少于一半,则为一半

(我加强调)

Java ArrayList不会执行此操作-删除元素后不会减少存储量。但是作者正在谈论(或相信ArrayList确实)减小了数组的大小。 在那种情况下,从最坏的情况来看,您可以说复杂度为O(n),因为减小大小涉及将n元素复制到缩小的数组中。

结论:

尽管对于Java ArrayList实现而言并非如此,当本书的作者谈论“动态数组”时,它会在必要时在删除时“减小数组大小”,然后数组末尾删除的大小写复杂度确实是O(n)

答案 1 :(得分:5)

该条目似乎是

  1. 不正确,或
  2. 是的,但具有误导性。

您绝对可以在动态数组的最后位置销毁对象,然后减小大小以删除最后一个元素,这是绝对正确的。在动态数组的许多实现中,有时需要执行调整大小操作,以确保分配的数组的大小在元素数量的一定常数范围内。如果发生这种情况,则是的,您需要创建一个新数组,复制旧元素,并释放之前的数组,这确实需要时间O(n)。但是,您可以证明这些调整大小的频率很少,因此从末尾进行删除的平均成本为O(1)。 (从技术角度上讲,从末端删除元素的摊销成本为O(1))。也就是说,只要您只在乎执行一系列操作的总成本,而不在乎任何单个操作的成本,那么假装每次操作花费的时间为O(1),就不会错。

我要说的是您最有可能查看材料中的错字。查看它们的末尾条目,以区分未完成案例和已完成案例,我认为这很可能是复制/粘贴错误。在表的开头,应该说出“如果数组不是'太空',则为O(1),否则为O(n)”的效果。但是,请再次记住,每个操作的摊销效率为O(1),这意味着这些可怕的O(n)项实际上在实践中不太可能会烧死您,除非您处于专业环境,每个操作都需要真正快速地工作。

答案 2 :(得分:1)

在动态数组(ArrayList)的Java中,最后一个元素的时间复杂度删除为 o(1),在Java中它不复制数组 在Java中,他们将检查天气,数组索引是否结束。

  int numMoved = size - index - 1;
        if (numMoved > 0)
         //copy array element 

答案 3 :(得分:1)

插入和删除是我们通常不对数组执行的操作,因为它们本质上具有固定的长度。您不能增加或减少某种东西的长度,这种东西的性质决定了它。

当人们谈论Java中的“动态数组”时,他们倾向于使用class ArrayList,它由数组支持,并提供了插入和删除元素的能力的幻觉。

但是,为了使某些软件提供对数组执行插入和删除操作的错觉,每次(或几乎每次都有可能的优化),它都必须分配一个新的具有所需长度的数组,并视情况复制旧阵列到其中,跳过已删除的元素或添加插入的元素。该数组副本是O(N)的来源。

并且,由于ArrayList执行的优化,您发布的表不准确:如果数组没有缩小很多,它应该说'O(1),如果数组没有缩小很多,它应该说O(N)。阵列缩小了太多,以至于重新分配被认为是必要的”。但是我想那太长了,无法放入表格单元格中。

答案 4 :(得分:1)

正如您提到的那样,如果将元素添加到动态数组中,它将以恒定的间隔更改其大小,并且会创建一个新数组,将元素复制到新数组中,这可能会造成混淆。而且,当尺寸缩小时,如果需要,它也会避开。

例如,如果在添加1st,2nd,3rd,4th元素时,interval为4,则一切都会好起来,但是当添加5th项时,动态数组将增长为8个元素的数组,并将所有元素复制到新数组。

减小时相同。如果您从间隔为4的5项数组中删除一项,则动态数组会创建一个新的4元素数组并复制这些元素。

这是一个很好的代表性视频tutorial

是的。如您可能已经知道的,当动态数组不必缩小时,它是O(1),它需要删除元素,但是当它必须缩小其O(n)时,

当您找到大的O符号时,您就定义了最坏的情况,所以它就是O(n)

答案 5 :(得分:0)

据我认为 由于它是一个动态数组,因此计算机系统不知道该动态数组的当前长度是多少,因此要找到此动态数组的长度,需要O(n)时间,然后需要O(1)时间才能删除。最后的元素。

答案 6 :(得分:0)

从动态数组(Java中的ArrayList)中删除项目需要搜索,然后删除

如果元素位于列表的末尾,则Search本身将导致n的计算时间。我希望这对您有意义。

您可以通过http://www.docjar.com/html/api/java/util/ArrayList.java.html

查看源