java.util.LinkedList不允许您快速删除列表中的给定对象。 remove(object)方法执行线性搜索以查找列表中的对象,以便可以将其删除。由于这是一个双链表,因此只需更新指针(node.prev和node.next)即可删除。
此问题的Java标准解决方案是什么?
注意1:迭代时我不想删除。我知道这很快,但我不是首先在我的元素中迭代。
注意2:为了简化:给定一个对象O,我知道它在双链表中,我想快速从该列表中删除O(通过更新指针),而不必在其中进行线性搜索。 list,如java.util.LinkedList那样。
答案 0 :(得分:14)
你应该看一下LinkedHashSet课程。基本上它是一个HashSet,在其条目中维护一个双向链表。它支持O(1)中元素的检索(因此也是删除)(希望如此)。如果要重新插入条目和其他详细信息,请查看链接以获取有关如何处理元素顺序的规范。
修改强>
如果您需要存储重复项,可以查看Guava LinkedHashMultiset(目前从未使用过)。关于Multiset的Guava用户指南是here。
答案 1 :(得分:2)
我敢打赌,LinkedList#remove()
的实现会通过更新指向前一项和下一项的指针来删除它 - 问题是,它必须遍历所有对象,直到找到要删除的正确对象为止。 / p>
如果您希望更快地删除集合而不迭代所有对象,请使用Set
或Map
。
答案 2 :(得分:1)
听起来你需要一个复合对象。创建一个包含列表的类,同时还保留该列表的索引。
因此,当您想要快速删除时,您需要进行常量时间索引查找,以获取对要删除的列表元素的引用,然后执行常量时间删除。
答案 3 :(得分:1)
我主要是一名学习Java的C程序员。我找到了这个帖子,因为我也想知道为什么没有链接列表实现,你可以直接删除对象而不搜索它。线性搜索是非常低效的。使用哈希表支持的列表更好,但您并不真正知道哈希表的执行方式。
你可以在C中轻松实现这一点的原因是因为通常列表元素对象本身包含下一个和前一个指针,所以给定对象,操作一些指针来删除元素是一个简单的问题。列表,所以它是一个O(1)操作。在Java中,您拥有该对象,但您无法直接访问指针,因为它们在列表中单独维护。因此,您必须线性搜索对象或使用哈希表搜索对象。
似乎可以通过创建链表实现来解决这个问题,其中添加到列表中的每个对象类型都必须实现LinkedListElement接口,该接口将支持获取和设置下一个和前一个指针。您必须添加下一个和上一个指向您的类的指针,并实现获取和设置它们的函数。然后链接列表类可以轻松删除对象,因为对象本身包含指针。
答案 4 :(得分:0)
通常,您希望尽可能使用ListIterator
。它是remove
将是恒定的时间。
Java标准库没有单独的链表节点结构,因此我认为ListIterator
是最佳选择。
答案 5 :(得分:0)
也许地图是合适的。它提供预期的 O(1)删除时间。但是你又没有指定 fast 的含义。
BST支持的列表也可以使用。它会给log(n)移除时间。
对于此处列出的解决方案,我假设更快地迭代列表,所以比O(n)更快;