我有LinkedList
个对象,以及指向我要删除的LinkedList
对象的指针。
有一个方法remove(object o)
,可用于删除一个对象,但正如文档所描述的那样,它逐个检查所有元素,并选择一个对象,这在语义上是相同的。
但这种方法不符合我的要求。
由于我有一个指向我要删除的对象的指针,我应该能够在O(1)
时删除它,因为LinkedList
是一个双向链表。 如果没有实施我自己的LinkedList
课程,还有其他方法吗?
答案 0 :(得分:3)
如果您拥有的只是对象本身的引用,则无法从O(1)中的LinkedList
删除对象。
如果通过调用迭代器上的remove()
将ListIterator<E>
对象放在要删除的项目上,则可以删除对象,但它没有多大帮助,因为你的迭代器会在列表被修改时失效。
以下是如何保留删除O(1)的示例。但搜索仍为O(n):
List<String> list = new LinkedList<>();
list.add("hello");
list.add("world");
list.add("one");
list.add("two");
list.add("three");
System.out.println(Arrays.toString(list.toArray()));
ListIterator<String> iter = list.listIterator();
String s;
while ((s = iter.next()) != null && !s.equals("world"))
;
// When it is time to delete
iter.remove();
System.out.println(Arrays.toString(list.toArray()));
由于ConcurrentModificationException
,编写自己的LinkedList<E>
实现并保留对节点的引用以供将来删除仍然是纯链接列表的最佳选择。
您的另一个选择是使用LinkedHashSet<E>
,它提供可预测的枚举顺序和O(1)删除,以换取使用更多内存。
答案 1 :(得分:1)
怎么样:
public void remove(Car searchedFor) {
for (Iterator<Car> it = list.iterator(); it.hasNext(); ) {
Car c = it.next;
if (c == searchedFor) {
it.remove();
}
}
}
答案 2 :(得分:1)
我的问题的一个很好的解决方案是同时使用List
和HashSet
。由于我们使用的是HashSet
,因此无法使用重复项。
插入:同时插入List
和HashSet
。 O(1)
时间
删除:从HashSet
删除(如果存在)。 O(1)
时间
遍历:遍历List
。仅在HashSet
包含该对象时访问。
请注意,我并不是想在这里复制LinkedList
的工作。我只是分享对我有用的东西。