【问题标题】:How to efficiently remove an element from java LinkedList如何有效地从 java LinkedList 中删除元素
【发布时间】:2013-12-25 12:49:38
【问题描述】:

我有一个算法,我以某种方式通过图中的节点,偶尔通过同一个节点几次,我需要形成一个通过节点的列表,这样一个节点最后出现一次我过去的时间。

例如,如果我通过节点A -> B -> C -> A -> C,我最终需要的列表是[B, A, C]

我想做的是使用 LinkedList,这样图表中的每个节点都将包含对其在 LinkedList 中的节点的引用。那么,每经过一个节点,我都会将其对应的节点从LinkedList中取出,重新插入到LinkedList的末尾,操作的复杂度只会是O(1)

但是,当我开始实现它时,我遇到了一个问题:显然,Java 类 LinkedList 不允许我看到它的实际列表节点。使用 LinkedList 的常规删除函数来删除包含给定图形节点的列表节点将是 O(n) 而不是 O(1),否定了使用 LinkedList 的全部意义。

当然,我可以自己实现 LinkedList,但我宁愿避免这样做 - 在我看来,如果我必须在 java 中实现 LinkedList,我做错了。

那么,有没有办法解决这个问题,而无需我自己实现 LinkedList?有什么我遗漏的吗?

【问题讨论】:

  • 你是对的,API 在这一点上很糟糕。 LinkedList 的内部工作是不公开的,甚至在时间上也不是恒定的。 LinkedList 中的 Node 类的名称已经随着时间的推移而更改。我想您唯一的选择是创建自己的课程。您可以复制粘贴 LinkedList 源代码并根据需要进行修改。
  • 问题是,你应该如何在重新插入时从列表中找到元素?
  • 每个图节点都持有对其列表节点的引用。当我通过图形节点时,我使用这个引用从列表中删除节点,然后将图形节点插入到列表的末尾(并将引用保存到新的列表节点,插入到末尾的那个列表)。
  • @Sage 如果你写出你的 cmets 作为答案,我会感谢你帮助我......
  • @Nayish,对不起,实际上我认为您是对的,我应该将其发布为将来可能搜索的人的答案。谢谢你:)

标签: java performance collections linked-list


【解决方案1】:

看起来,你期待一个内置的方法,我不认为有任何 Collection 提供这样的功能。您必须按照@MartijinCourteaux 的建议自行实施。或者:

  • 使用像TreeSet<E> 这样的Sorted Set 集合,支持成本为O(log n) 用于操作:add, remove and contains
  • LinkedHashSet<E> 但请注意,与 HashSet<E> 不同,LinkedHashSet 可以有 O(1) 预期的操作性能:add, contains, remove 但性能可能略低于 HashSet,因为维护的额外费用链表。但是我们可以使用它而不会增加与TreeSet 相关的成本。但是,如果将元素重新插入集合中,插入顺序不会受到影响,因此请尝试在重新插入之前删除元素的第一次插入

【讨论】:

    【解决方案2】:

    LinkedHashMap 保持输入值的顺序,并允许通过其键删除节点,然后放回末尾。我想这就是你所需要的。

    【讨论】:

      【解决方案3】:

      除非您的链表很大,否则即使使用改组,仅使用常规数组列表也会提供快速的性能。如果顺序不重要,您还应该考虑使用散列集,如果插入的顺序很重要,则应考虑使用链接散列集,或者如果您希望对其进行排序,则使用树集。它们不允许重复值,但在插入、删除和包含方面具有良好的 O 性能。

      【讨论】:

        猜你喜欢
        • 2014-05-20
        • 1970-01-01
        • 2010-11-05
        • 1970-01-01
        • 1970-01-01
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 2019-08-01
        相关资源
        最近更新 更多