从链接列表的开头删除所有

时间:2012-07-18 17:24:42

标签: java linked-list java-7

我正在查看Java 7的LinkedList API并注意到一些好奇的东西。似乎没有“删除之前(或之后)”类型的方法。例如,如果我有一个100元素LinkedList,并且我想删除前20个元素,Java似乎强制您一次删除一个元素,而不是将开始指针移动到第21个元素并删除20之间的链接看起来这是一个可以在O(1)时间内完成的操作,而不是O(n)时间,因为Java似乎迫使你这样做。

我在这里遗漏了什么,或者它只是Java中的一个明显漏洞?

修改

我知道List接口中的sublist(int, int)方法。我仍然认为这比通用的“切掉第一个(或最后一个)n”用例的效率略低。

编辑2

对每个指出找到第n个元素的人都不是O(1)的人。无论切断前n-1个元素的容易程度如何,找到第n个元素仍然需要O(n)时间。

然而,正如Dilum Ranatunga指出的那样,在给定位置存在迭代器的可能性。在这种情况下,说“我在这里,在我之前删除所有”仍然是有用的。

6 个答案:

答案 0 :(得分:5)

无论你做什么,它仍然是O(n)操作。

您无法直接访问链接列表的各个节点,因此您必须首先遍历列表才能访问第21个节点。一旦你在那里,O(1)就会“重新排列”列表,但它仍然是整个原子操作的O(n)。

答案 1 :(得分:1)

LinkedList从List接口继承子列表方法。可在此处找到信息http://docs.oracle.com/javase/6/docs/api/java/util/List.html#subList(int,int)

答案 2 :(得分:1)

您可以致电list = list.subList(21, list.size())从21到列表末尾获取sublist

操作是O(1),但是你没有得到LinkedList,你得到的AbstractList.SubList就像原始LinkedList的包装类一样,委托方法子列表的偏移量。

虽然这是一个恒定时间,但重要的是要注意这不是一个新列表。如果列表大小从n变为m,则列表中调用的后续线性时间方法仍将在O(n)中运行,而不是在O(m)中运行。

答案 3 :(得分:1)

不可能立即跳转到第N个元素,因为每个先前节点都包含Node.next的地址(链中的下一个节点)。所以它必须自然地遍历导致O(n)运行时的20个元素。

例如:

[节点1,节点2的地址] - > [节点2,节点3的地址] - >等... - > [节点20,节点21的地址]

如果没有首先进入节点20,就无法获得“节点21的地址”,为此,您需要从节点19中“寻址节点20”,依此类推。

答案 4 :(得分:1)

在O(1)时间内查找项目n的算法是什么?这仍然是一个O(n)操作,用于定位第n个项目并将其设置为头部。与20删除相比,你可以保存一些中间指针赋值,但不是一个巨大的收益。

答案 5 :(得分:0)

Java的java.util.List定义了API listIterator()ListIteratorprevious()

所以你想要的成语是:

// some loop construct {
  listIter.previous();
  listIter.remove();
}