Java - LinkedList push()pop()意味着它是一个堆栈,而不是一个队列?

时间:2016-09-18 08:21:11

标签: java data-structures linked-list queue

在我的数据结构类中,我了解到LinkedList是一个队列。就像现实生活中的一条线,第一个进入生产线的人将是第一个离开的人。说得通。如下所示,ListedList实现了Queue,其具有FIFO(先进先出)过程。

但是如果你看一下方法push(E)pop()的描述,它们的内容如下:

推(E)

  

将元素推送到此列表所表示的堆栈中。换句话说,将元素插入此列表的前面。

pop()方法

  

从此列表表示的堆栈中弹出一个元素。换句话说,删除并返回此列表的第一个元素。

那......不是队列。这是一个堆栈。 push无法访问通过pop进入LinkedList的第一个元素,直到pop()之后添加的每个元素都被addFirst(E)删除。

这是为什么?我知道LinkedLists可以用作堆栈(如果你只使用removeFirst()addFirst(E))并且可以用作队列(如果你只使用removeLast()和{{1}反之亦然)那么为什么会这样呢?我觉得pop()应该删除并返回最后一个元素,或者push(E)应该在LinkedList的末尾添加元素。然后它会更有意义。

TLDR:为什么LinkedList&#39; pushpop意味着当LinkedList实际实现Queue时,它会作为堆栈运行。< / p>

enter image description here

5 个答案:

答案 0 :(得分:2)

Push()pop()按惯例操作与StacksDeque相关,更具体地说,在此上下文中),这就是为什么您应该期望{ {1}}在使用这些方法时以这种方式工作。 如果您希望LinkedList作为LinkedList工作(它实现Queue接口),您要使用的方法(如文档中所述)为Queueadd()

See LinkedList Documentation

答案 1 :(得分:1)

您提到的方法(push()pop())来自Deque界面,该界面也由LinkedList实施。 Deque状态的Javadoc:

  

支持两端插入和移除元素的线性集合。名称deque是&#34;双端队列&#34;的缩写。并且通常发音为#34; deck&#34;。大多数Deque实现对它们可能包含的元素数量没有固定的限制,但是这个接口支持容量限制的deques以及没有固定大小限制的deques。

换句话说,它与常规队列不同。

如果您确实想将LinkedList用作队列,则应将该变量分配给该接口:

Queue<String> queue = new LinkedList<>();

这样做,您只能将queue用作队列。此接口定义了add()remove()以及其他方法,用于在队列中添加和删除元素。

答案 2 :(得分:0)

LinkedList是一个双端队列(Deque),因此您可以从两端添加和删除元素。它还实现了List,它允许你修改中间的部分。

这不会改变使用add / offerpoll / remove将其用作队列的事实。

答案 3 :(得分:0)

从类图中可以看出,LinkedList既是List AND 又是Deque

Deque接口定义了一个&#34;双端队列&#34;抽象可以同时充当FIFO(即堆栈)或LIFO(即Queue)......来自javadocs

  

Deques也可以用作LIFO(后进先出)堆栈。应优先使用此接口,而不是旧版Stack类。当deque用作堆栈时,元素将从双端队列的开头推出并弹出。

来自push API的FIFO端的popDeque操作com。

  

LinkedList - push()pop()表示它是一个堆栈,而不是一个队列?

从逻辑上讲,这是不正确的。

  • 你是正确的push()pop()意味着堆栈。
  • 但是,只有add()remove()缺席才表示不是队列。

FIFO和LIFO功能并不相互排斥。

答案 4 :(得分:0)

单链接列表是一个很好的堆栈,但只有一个非常糟糕的队列。只有双链的双根列表才适合作为队列。

单链表允许仅在头部插入和移除O(1)(即堆栈操作)。

查找tail元素需要遍历O(n)中的所有列表(除非它是双根的)。删除尾部需要您修改倒数第二个元素。为了提高效率,你需要一个双链表(双根不足以制作O(1))

但是,当然任何双链表都继承了从单链表开始作为堆栈运行的能力。你仍然可以在O(1)中访问头部。所以队列堆栈没有矛盾。

请注意,在Java实际中,由于开销,LinkedList几乎总是一个坏主意。既不应该使用堆栈也不应该使用队列,但是除非经常在大型列表的中间中插入或删除对象,否则您应该总是喜欢基于数组的实现。 (实际上,基准LinkedList - 它非常慢且内存昂贵。)