这是来自 CLRS 3rd 的练习:
10.2-3通过单链表L实现队列。操作ENQUEUE和DEQUEUE仍然需要O(1)时间。
使用单链表实现队列并不困难。我的问题是关于时间的复杂性。如何实现取O(1)?
的ENQUEUE和DEQUEQUE我在google上发现的东西就像使用指针来跟踪头部和尾部。现在问题变成如何使用O(1)时间在单链表上跟踪头尾?恕我直言,需要O(n)跟踪尾巴。我对吗?
答案 0 :(得分:15)
管理头尾指针需要O(1)时间。
入队:
tail -> next = newNode;
newNode -> next = NULL;
tail = newNode;
出列:
output_node = head;
head = head -> next;
// do whatever with output_node;
注意:在执行指针分配之前,您还必须执行边界检查和内存分配/解除分配
答案 1 :(得分:3)
它很简单,只需在末尾使用enque,然后在前面使用deque,并设置2指针(或unique_ptrs)指向end和front,这样做。像这样:
struct queue{
Node *head;
Node *tail;
int node_cnt; // well, you can put this in if you like
};
Node *enque(Node *head, int data)
{
Node *p = new Node(Node data);
if (head)
{
head->next = p;
head = p;
}
else
head = p;
++ q.node_cnt;
return head;
}
int deque(Node *tail)
{
Node *p = tail;
int x = tail->data;
tail = tail.next();
delete p;
-- q.node_cnt;
return x;
}
上面只是一个演示代码,但你可以看到你不需要遍历整个列表来进行enque或deque。
答案 2 :(得分:2)
std::list
个容器,那么<p> std
就是您要找的。
如果没有(我认为是这种情况),请尝试回答这个问题:为什么需要执行n次操作?你能将指针存储到末尾吗?
说,你有一个有意思的链接列表和一个指针head
和tail
列表项具有next
指针。
next
指针并重新指向新项目的head
指针。这是3次操作= O(1)last
指针移动到最后一个项目的next
指针所指向的指针并删除该项目 - 2次操作= O(1)