这是我使用双向链表的队列的实现:
QUEUE-EMPTY
if L.head == NIL
return True
else return False
QUEUE(x):
if L.head == NIL:
x.prev = NIL
L.head = x
else
cur = L.head
while cur.next != NIL
cur = cur.next
cur.next = x
x.prev = cur
x.next = NIL
DEQUEUE():
x = L.head
L.head = x.next
x.next.prev = L.head
return x
如何改善?这是对的吗?
是否有制作QUEUE O(1)的意思?
谢谢!!
答案 0 :(得分:1)
请参阅下面的更改+评论:
QUEUE(x):
if L.head == NIL:
x.prev = x.next = NIL // otherwise you never set up next
L.head = x
else
cur = L.head
while cur.next != NIL
cur = cur.next
cur.next = x
x.prev = cur
x.next = NIL
DEQUEUE():
// handle empty queue
if L.head == NIL:
ERROR! // or something
else
x = L.head
L.head = x.next
if x.next != NIL: // handle empty queue
x.next.prev = L.head NIL // otherwise it points to itself
return x
要使QUEUE(x)
O(1),您需要保留指向尾部的指针。
QUEUE(x):
if L.head == NIL:
x.prev = NIL
L.head = L.tail = x
else
cur = L.tail
cur.next = L.tail = x
x.prev = cur
x.next = NIL
DEQUEUE():
if L.head == NIL:
ERROR! // or something
else
x = L.head
L.head = x.next
if x.next != NIL:
x.next.prev = NIL
else
L.tail = NIL
return x
此外,您并不需要双链表。单链表应该可以正常工作(除非你也想支持其他操作)。
答案 1 :(得分:0)
队列有两种标准实现。
环形缓冲区可以存储在一个数组中,指向头部和尾部。所有算术都以数组的长度为模。如果尾部赶上头部,队列就会溢出,无法再使用。
另一个实现使用两个链接列表。第一个列表是队列的前面,按顺序;第二个列表是队列的后面,顺序相反。项目将添加到第二个列表中,并从第一个列表中检索。只要第一个列表为空并且要提取项目,第二个列表就会反转并成为第一个列表,并创建一个新的(空)第二个列表。
两种实现都具有插入和获取/删除的时间复杂度O(1)。环形缓冲区实现具有绝对时间复杂度O(1),但预定义了队列的最大大小。链接列表实现具有摊销时间复杂度O(1),但假设有足够的内存可用,则对队列的最大大小没有限制。