ArrayList:在指定元素处插入与插入

时间:2017-03-24 06:19:36

标签: java arraylist data-structures abstract-data-type

考虑一个Arraylist。在内部它不是满的,到目前为止插入的元素数量是已知的。元素未排序。 无论ArrayList中包含的元素数量如何,选择下面列出的快速操作。 (换句话说,只需要执行几条指令)。

插入

在给定索引处插入

从指定索引获取数据

查找整数数组中的最大值(不一定排序)

在给定索引处删除

替换指定索引处的元素

搜索特定元素

我在指定的索引处选择了Insertion,从指定的索引获取数据,并替换了一个元素,但是回答键是Insertion。正如我通常所理解的那样,在ArrayList中,插入操作要求所有元素向左移动。如果我们在列表的开头做到这一点,我们将有$ O(n)$时间复杂度。但是,如果我们在最后完成它,它将是$ O(1)$。

我的问题归结为:(1)在指定索引处的插入和插入之间存在什么差异(2)如果考虑到这个特定的时间复杂度,为什么它被考虑"快速"

4 个答案:

答案 0 :(得分:0)

对于第一个问题,答案是:

  • 在指定的索引i插入O(n),因为i后的所有元素都必须向右移动一个位置。
  • 另一方面,JavaArrayList.add())中实现的简单插入只会占用O(1),因为该元素会附加到数组的末尾,因此不需要移位

对于第二个问题,很明显为什么简单的插入很快:不需要额外的操作,所以时间是恒定的。

答案 1 :(得分:0)

  

(1)在指定的索引和

处插入和插入之间存在什么差异(如果有的话)

ArrayList连续存储它的元素。添加到ArrayList的末尾不需要以任何方式更改ArrayList,除了将新元素添加到其自身的末尾。因此,该操作是O(1),当想要在数据结构中重复执行动作时采用有利的恒定时间。

但是,向索引添加元素需要ArrayList以某种方式为元素腾出空间。怎么做的?插入元素后面的每个元素都必须移动一步,以便为新插入腾出空间。您的索引是第一个元素和第n个元素之间的任何内容(包含)。因此,该操作最多为O(1),最坏的是O(n),其中n是阵列的大小。对于大型列表,O(n)比O(1)花费的时间要长得多。

  

(2)考虑到这种特定的插入时间复杂性,为什么它被认为是“快”

它被认为是快速的,因为它是O(1),或恒定时间。如果时间复杂度实际上只是一个操作,它尽可能快,其他小常量也被认为是快速的,并且通常由O(1)同样表示,其中“1”并不意味着严格单一操作但是,操作量不依赖于其他东西的大小,在您的示例中,它将是ArrayList的大小。然而,恒定的时间复杂度也可能涉及大的常数,但通常被认为是尽可能最快的时间复杂度。为了将其置于上下文中,O(1)操作在具有1000个元素的ArrayList中执行大约1 * k个操作,而O(n)操作需要大约1000 * k个操作,其中k是一些常量。

Big-O表示法用作度量标准,用于衡量操作或整个程序在运行时将执行的操作数。

有关大O符号的更多信息: What is a plain English explanation of "Big O" notation?

答案 2 :(得分:0)

首先看看java.util.ArrayList

中定义的这两种方法
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}
  1. 现在,如果你看到第一个方法(只是添加元素),它只是确保是否有足够的容量,元素追加到列表的最后一个。
    因此,如果有足够的容量,那么此操作将需要O(1)时间复杂度,否则需要移位所有元素,最终时间复杂度增加到O(n)
  2. 在第二种方法中,当你指定索引时,该索引之后的所有元素都会被移位,这肯定会花费更多的时间。

答案 3 :(得分:0)

ArrayList内部只是一个数组本身,它使用Array.copyOf创建一个增加大小的新数组,但是原始内容完好无损。 所以关于插入,无论你做一个简单的添加(将在数组的末尾添加数据)还是在第一个(第0个)索引上,它仍然会比大多数数据结构更快,同时要记住简单性数据结构。

唯一的区别是简单的add不需要遍历,但是在索引处添加需要将元素向左移动,类似于删除。这使用System.arrayCopy将一个数组复制到另一个数组,并改变了索引和数据。

所以,是的简单插入比索引插入更快。