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

LinkedList的O(1)复杂度的add(int,E)如何?

南宫喜
2023-03-14
问题内容

从链接列表标签Wiki摘录:

链表是一种数据结构,其中的元素包含对下一个(以及可选的上一个)元素的引用。链接列表可 在任何位置 提供 O(1)插入和删除
,O(1)列表串联,以及在前(和可选)后位置的O(1)访问以及对下一个元素的O(1)访问。随机访问具有O(N)的复杂度,通常没有实现。

(强调我的)

令我惊讶的是,该列表如何以比简单 读取 该索引低的复杂度 插入 一个随机索引? __

因此,我查看了的源代码java.util.LinkedList。该add(int, E)方法是:

public void add(int index, E element) {
    addBefore(element, (index==size ? header : entry(index)));
}

addBefore(E, Entry<E>方法只是指针的重新分配,但是还有entry(int)方法:

if (index < 0 || index >= size)
        throw new IndexOutOfBoundsException("Index: "+index+
                                            ", Size: "+size);
    Entry<E> e = header;
    if (index < (size >> 1)) {
        for (int i = 0; i <= index; i++)
            e = e.next;
    } else {
        for (int i = size; i > index; i--)
            e = e.previous;
    }
    return e;
}

即使进行了一半大小的优化,for这里的循环(一个或另一个)对我来说似乎都是死胡同,这种方法(因此add(int, E))在O(n)时间的最小最坏情况下运行,并且肯定不是恒定的时间。

我想念什么?我是否误解了big-O表示法?


问题答案:

好的,它们确实支持在任意位置进行固定时间插入-但 前提是
您碰巧有一个指向列表条目的指针,您想在列表条目之后或之前插入某个条目。当然,如果只有索引,这将无法正常工作,但这不是您通常在html" target="_blank">优化代码中执行的操作。

在Java中,您也可以这样做,但只能使用列表迭代器。

相较于数组列表,链表的此属性是它们的最大优点–例如,如果要从聊天室的用户列表中删除用户,则可以将指向用户位置的指针存储在用户的用户列表中,以便,当他想离开房间时,可以将其实现为一项O(1)操作。



 类似资料:
  • 问题内容: 为什么ArrayList的add()和add(int index,E)复杂度要按固定时间摊销? 为什么不对单个add()操作使用O(1),对单个add(int索引,E)操作使用O(n),而对于使用任一(任何)添加方法添加n个元素(n个添加操作)的O(n)呢?假设我们很少使用add(int index,E)添加到数组末尾? 数组(和ArrayList)的操作复杂度已经不是n个元素了: a

  • 问题内容: 我打算对StringBuilders中的最后一个字符进行很多删除。使用的解决方案对我来说很好。但是,由于这些删除将处于循环中,因此我需要知道其复杂性。 据我了解,该操作只是减少了StringBuilder对象的一些私有属性,并且不对字符本身执行任何复制/克隆/复制操作,因此它的时间为O(1),应该可以快速运行。 我对吗? 问题答案: 从文档中: 设置字符序列的长度。序列更改为新的字符序

  • 下面是链接:array reversed() 在讨论部分的最后,它说复杂性O(1),我相信这是关于时间复杂性的,如何反转一个数组需要O(1)时间?

  • 在最近的一次测试中,我们得到了一个函数来计算未排序的ArrayList中出现了多少个double(不是原语double,而是一个项目出现了两次)。 我正确地确定了Big O复杂度为O(N^2),但由于我错误地确定了全部复杂度,因此只获得了部分学分。函数如下: 在他刚刚发布的考试解决方案中,他给出了这样的解释: 输入集合中有N个项,该方法通过一个缩减步骤反复调用自己,该步骤生成一个新索引N次,直到达

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

  • 我对在LinkedList开头插入元素的时间复杂性感到好奇。我知道LinkedList本身会将现有元素向右移动一个索引,但要做到这一点,它会进行与列表中现有元素一样多的迭代吗? 另外,最好的方式是在开头插入offerFirst吗?