我正在努力实现双端队列作为双向链接列表(用于个人致富),我想知道是否有人介意看看我的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;
}
答案 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;
}