在我的数据结构类中,我了解到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
' push
和pop
意味着当LinkedList
实际实现Queue
时,它会作为堆栈运行。< / p>
答案 0 :(得分:2)
Push()
和pop()
按惯例操作与Stacks
(Deque
相关,更具体地说,在此上下文中),这就是为什么您应该期望{ {1}}在使用这些方法时以这种方式工作。
如果您希望LinkedList
作为LinkedList
工作(它实现Queue
接口),您要使用的方法(如文档中所述)为Queue
, add()
。
答案 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
/ offer
和poll
/ remove
将其用作队列的事实。
答案 3 :(得分:0)
从类图中可以看出,LinkedList
既是List
AND 又是Deque
。
Deque
接口定义了一个&#34;双端队列&#34;抽象可以同时充当FIFO(即堆栈)或LIFO(即Queue
)......来自javadocs:
Deques也可以用作LIFO(后进先出)堆栈。应优先使用此接口,而不是旧版
Stack
类。当deque用作堆栈时,元素将从双端队列的开头推出并弹出。
来自push
API的FIFO端的pop
和Deque
操作com。
LinkedList
-push()
,pop()
表示它是一个堆栈,而不是一个队列?
从逻辑上讲,这是不正确的。
push()
和pop()
意味着堆栈。add()
和remove()
的缺席才表示不是队列。FIFO和LIFO功能并不相互排斥。
答案 4 :(得分:0)
单链接列表是一个很好的堆栈,但只有一个非常糟糕的队列。只有双链的双根列表才适合作为队列。
单链表允许仅在头部插入和移除O(1)(即堆栈操作)。
查找tail元素需要遍历O(n)中的所有列表(除非它是双根的)。删除尾部需要您修改倒数第二个元素。为了提高效率,你需要一个双链表(双根不足以制作O(1))
但是,当然任何双链表都继承了从单链表开始作为堆栈运行的能力。你仍然可以在O(1)中访问头部。所以队列和堆栈没有矛盾。
请注意,在Java实际中,由于开销,LinkedList
几乎总是一个坏主意。既不应该使用堆栈也不应该使用队列,但是除非经常在大型列表的中间中插入或删除对象,否则您应该总是喜欢基于数组的实现。 (实际上,基准LinkedList
- 它非常慢且内存昂贵。)