C++ 双端队列:这是一个合理的“吗?”;在前面加上“;实施

C++ 双端队列:这是一个合理的“吗?”;在前面加上“;实施,c++,queue,C++,Queue,我正在开发一个双端队列的实现,作为一个双链接列表(用于个人充实),我想知道是否有人介意看看我的PushFront函数,看看我是否走上了正确的道路。它本身应该是不言自明的(我希望如此) 我的想法是,我的头部和尾部哨兵被保留在末端,在我看来,这是避免边缘情况的最佳方式 编辑:为了避免任何混淆,我知道在标准库中已经为我完成了这项工作。我这样做是为了教自己一些关于语言的知识 编辑:看来我已经有了主意。现在有一个有趣的问题: void* DeQueue::PopFront() { if (Empt

我正在开发一个双端队列的实现,作为一个双链接列表(用于个人充实),我想知道是否有人介意看看我的PushFront函数,看看我是否走上了正确的道路。它本身应该是不言自明的(我希望如此)

我的想法是,我的头部和尾部哨兵被保留在末端,在我看来,这是避免边缘情况的最佳方式

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

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

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;
}
似乎是这样的

if (Empty()) {
    head->next = temp;
    tail->last = temp;
    temp->next = tail;
    temp->last = head;
当队列为空时,您假定头和尾已经指向某个对象了吗?

似乎是这样

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

当队列为空时,您假定头和尾已经指向某个对象?

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

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;
}

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

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;
}

关于哨兵,您只需要其中一个哨兵将包含列表的
下一个
(第一个)和
最后一个
指针。如果在初始化过程中指针指向前哨值,那么当列表为空时,不需要考虑特殊情况。

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


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

,只需要其中一个包含“代码”>下(第一)和<代码>最后< /代码>指针的列表。如果在初始化过程中指针指向前哨值,那么当列表为空时,不需要考虑特殊情况。

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



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

如果<代码>新< /C>抛出异常会发生什么?看起来对我来说是有效的。但我建议使用模板而不是void*。另外,在QueueItem的构造函数中分配QueueItem::data。@Als:如果new抛出异常,看起来很好。你在找什么?记得很好,谢谢。目前我并不担心异常处理。“我只是在寻找指针,看看它在概念上是否准确。”。我将把它添加到构造函数中,谢谢。如果
new
抛出异常,会发生什么情况?看起来它对我有效。但我建议使用模板而不是void*。另外,在QueueItem的构造函数中分配QueueItem::data。@Als:如果new抛出异常,看起来很好。你在找什么?记得很好,谢谢。目前我并不担心异常处理。“我只是在寻找指针,看看它在概念上是否准确。”。我将把它添加到构造函数中,谢谢。
这个想法是我的头部和尾部哨兵保持在末端
,他保证有两个哨兵节点。这不是一个问题,并且简化了很多算法。我假设头部和尾部彼此指向,若我做对了Pop()的话,在这种情况下,它们应该是对的。Empty()被确定为“tail->last==head”。
这个想法是我的head和tail哨兵保持在末端
,他保证有两个哨兵节点。这不是一个问题,并且简化了很多算法。我假设头部和尾部彼此指向,若我做对了Pop()的话,在这种情况下,它们应该是对的。Empty()被确定为“tail->last==head”。这里可能有更多的简化。也许
deleteme->next->last=head可能会有更多的简化。也许
deleteme->next->last=head我一定会考虑到这一点。谢谢,我一定会考虑的。非常感谢。