【问题标题】:Time complexity of inserting at the beginning of LinkedListLinkedList开头插入的时间复杂度
【发布时间】:2013-07-25 00:36:57
【问题描述】:

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

另外,在开头插入offerFirst的最好方法是什么?

【问题讨论】:

  • 为什么要移动剩余的元素? head 将指向新元素,其 next 将指向前一个 head。所以不应该是O(1)吗?
  • 像在 ArrayList 中一样移动,所以以前的元素 0 现在是 1
  • 链表不是数组。你正在创建我假设一个队列。队列可以使用链表或数组来实现。链表只是对指向内存的指针的操作。不涉及转移。
  • 在 LinkedList 的任何一端插入元素以及删除或检索都非常快。如果您想了解更多类似 offerFirst 的方法,请参阅 Internal life of LinkedLIst 教程

标签: java collections linked-list


【解决方案1】:

添加到LinkedList 的前面是在恒定时间内发生的:

public void addFirst(E e) 
{
    addBefore(e, header.next);
}

private Entry<E> addBefore(E e, Entry<E> entry) 
{
    Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
    newEntry.previous.next = newEntry;
    newEntry.next.previous = newEntry;
    size++;
    modCount++;

    return newEntry;
}

它不受元素需要移动的数组的支持。如您所见,需要做的只是一组参考重新分配。

编辑:

为了解决您对offerFirst 的担忧,以下是:

public boolean offerFirst(E e) 
{
     addFirst(e); 

     return true;
}

因此,正如我在评论中所说,仅当您希望返回 boolean 时才使用它。

【讨论】:

  • 只使用offerFirst 可以吗?即如果我这样做,列表会自动为我转移其余部分吗?
  • 查看代码和我的解释。这不是ArrayList——它没有数组支持。 LinkedList 是一组引用 previousnext 节点的节点。因此,您可以通过重新分配引用来添加和删除节点。没有必要改变任何东西。
  • 好的。实际插入怎么样。我应该只使用offerFirst吗?
  • 如果你想返回一个boolean,否则addFirst就可以了。
  • @amphibient 除了上面的评论,我还做了一个编辑。
【解决方案2】:

在列表的前面插入一个项目只会做两件事(都非常轻量级):

1) 更新 HEAD 指针(这是告诉我们第一个元素在哪里的指针)

2) 将新元素的 NEXT 指针设置为旧的 HEAD 元素。

这是一个非常轻量级的操作,代表了链表的优势之一。

我对Java不是很了解,但是由于offerFirst被设计为在列表的前面添加一个元素,这可能是最好的方法。

【讨论】:

    猜你喜欢
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多