双端队列:这是一个声音“添加到前面”的实现吗?

时间:2011-09-29 18:09:12

标签: c++ queue

我正在努力实现双端队列作为双向链接列表(用于个人致富),我想知道是否有人介意看看我的PushFront功能,看看我是否在正确的轨道上。它本身应该是不言自明的(我希望)。

void DeQueue::PushFront(void* item) {
    QueueItem* temp = new QueueItem();
    temp->data = item;
    // Insert the item between the head and the head's next item.
    if (Empty()) {
        head->next = temp;
        tail->last = temp;
        temp->next = tail;
        temp->last = head;
    } else {
        temp->next = head->next;
        temp->last = head;
        head->next->last = temp;
        head->next = temp;
    }
}

我的想法是我的头尾哨保持在两端,这在我看来是避免边缘情况的最好方法。

编辑:为了避免任何混淆,我知道标准库已经为我完成了这项工作。我这样做是为了教会自己一些关于语言的事情。

编辑:看来我已经明白了。现在一个有趣的问题:

void* DeQueue::PopFront() {
    if (Empty()) return NULL;  // should throw exception instead.
    void* temp = head->next->data;
    head->next->next->last = head;
    head->next = head->next->next;
    // now my node is gone... How do i free the memory
    // of something I've lost the reference to?
    return temp;
}

3 个答案:

答案 0 :(得分:2)

关于哨兵,您只需要其中一个包含列表的next(第一个)和last指针。如果指针在初始化期间引用了sentinel值,那么当列表为空时,您不需要考虑特殊情况。

关于弹出列表的第二个问题,你只需要保留一个指向节点的指针,并在从函数返回之前调用delete

此外,您可能需要考虑划分学习问题:使用智能指针管理资源并学习算法,然后学习内存管理(反之亦然)

答案 1 :(得分:1)

似乎这个

if (Empty()) {
    head->next = temp;
    tail->last = temp;
    temp->next = tail;
    temp->last = head;

你假设当队列为空时头部和尾部已经指向某个东西?

答案 2 :(得分:1)

回答第二次编辑:你不能。你必须保留对它的引用。

void* DeQueue::PopFront() {
    if (Empty()) 
        throw logic_error("stack is empty");

    QueueItem* deleteme = head->next; //get node
    void* temp = deleteme->data;

    deleteme->next->last = head;
    head->next = deleteme->next;

    delete deleteme; //delete node
    return temp;
}