如何使用单链表实现队列,使其ENQUEUE和DEQUEUE占用O(1)?

时间:2014-05-30 09:39:03

标签: c++ c algorithm data-structures

这是来自 CLRS 3rd 的练习:

  

10.2-3通过单链表L实现队列。操作ENQUEUE和DEQUEUE仍然需要O(1)时间。

使用单链表实现队列并不困难。我的问题是关于时间的复杂性。如何实现取O(1)?

的ENQUEUE和DEQUEQUE

我在google上发现的东西就像使用指针来跟踪头部和尾部。现在问题变成如何使用O(1)时间在单链表上跟踪头尾?恕我直言,需要O(n)跟踪尾巴。我对吗?

3 个答案:

答案 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次操作?你能将指针存储到末尾吗?

说,你有一个有意思的链接列表和一个指针headtail 列表项具有next指针。

  • 如果您将新项目排入队列,则只需添加一个新项目,修改前“第一个”项目的next指针并重新指向新项目的head指针。这是3次操作= O(1)
  • 如果您将某个项目出列,则将last指针移动到最后一个项目的next指针所指向的指针并删除该项目 - 2次操作= O(1)