从列表中删除范围(尾部)

2022-09-01 01:22:02

有没有一种有效的方法可以从中删除X元素的范围 - 比如尾巴 - 例如 在爪哇?ListLinkedList

显然,可以逐个删除最后的元素,这应该会导致O(X)级性能。至少对于实例,应该可以具有O(1)性能(通过在要删除的第一个元素周围设置引用并设置头/尾引用)。不幸的是,我没有看到任何方法可以一次删除最后的元素。LinkedListListLinkedList

目前,我正在考虑使用List.subList()替换列表,但我不确定它是否具有相同的性能。至少在代码中会更清晰,另一方面,我会失去提供的附加功能。LinkedList

我主要使用List作为堆栈,这似乎是最好的选择,至少在语义方面是这样。LinkedList


答案 1

subList(list.size() - N, list.size()).clear()是删除最后元素的推荐方法。事实上,Javadoc for subList 特别推荐了这个成语:N

此方法消除了对显式范围操作(数组中通常存在的那种)的需要。任何需要列表的操作都可以通过传递子列表视图而不是整个列表来用作范围操作。例如,以下成语从列表中删除一系列元素:

 list.subList(from, to).clear();

事实上,我怀疑这个成语可能比调用时间更有效(尽管是一个常数因子),只是因为一旦它找到倒数节点,它只需要更新链表中恒定数量的指针,而不是一次更新每个最后一个节点的指针。removeLast()NNN


答案 2

请注意,返回原始列表的视图,这意味着:subList()

  1. 对视图所做的任何修改都将反映在原始列表中
  2. 返回的列表不是 a - 它是不可序列化的内部实现LinkedListList

无论如何,使用其中一个或应该足够有效,因为在Java中弹出链表的第一个或最后一个元素是一个操作 - 在内部,保存指向列表两端的指针,并且删除任何一个都像将指针移动到一个位置一样简单。removeFirst()removeLast()O(1)LinkedList

为了一次删除元素,您仍然会遇到性能问题,尽管奇怪的是,它可能是一个更好的选择,因为删除末尾的元素就像将索引指针(表示数组的末尾)向左移动一个位置一样简单,并且没有垃圾节点像.最好的选择?尝试这两种方法,分析它们,让数字自己说话。mO(m)LinkedListArrayListArrayListLinkedList