我有以下两个函数,我可以让removeAfter函数正常工作,但是当试图实现removeBefore函数时,链接列表根本没有改变。我错过了什么吗?我已经做了必要的更改,但仍然得到相同的结果:removeBefore不会输出任何更改列表。
// remove the node after the node p
void DoublyLinkedList::removeAfter(DListNode &p){
if (isEmpty()){
throw EmptyDLinkedListException("Empty Doubly Linked List");
}
DListNode *to_delete = &p;
to_delete = to_delete->next;
if (to_delete != NULL){
if(to_delete->next != NULL){
to_delete->prev->next = to_delete->next;
}
if(to_delete->prev != NULL){
to_delete->next->prev = &p;
}
if (to_delete == &trailer) {
trailer = *to_delete->prev;
}
}
if (to_delete == NULL){
throw EmptyDLinkedListException("Cannot delete a null pointer");
}
delete to_delete;
}
// remove the node before the node p
void DoublyLinkedList::removeBefore(DListNode &p){
/* Complete this function */
if (isEmpty()){
throw EmptyDLinkedListException("Empty Doubly Linked List");
}
DListNode *to_delete = &p;
to_delete = to_delete->prev;
if (to_delete != NULL){
if (to_delete->next != NULL) {
to_delete->next->prev = to_delete->prev;
}
if (to_delete->prev != NULL) {
to_delete->prev->next = to_delete->next;
}
if (to_delete == &header) {
header = *to_delete->next;
}
}
if (to_delete == NULL){
throw EmptyDLinkedListException("Cannot delete a null pointer");
}
delete to_delete;
}
答案 0 :(得分:1)
您的代码中存在错误。
首先,链表是一个指针列表,因此不习惯通过引用传递节点。你真的应该用指针传递它们。
removeAfter()
没有考虑输入时p.next
可能为NULL的可能性(当p
是列表中的最后一个节点时)。并且在删除to_delete
之前,它不会正确更新to_delete
的兄弟姐妹。它看起来应该是这样的:
void DoublyLinkedList::removeAfter(DListNode *p)
{
DListNode *to_delete = p->next; //Get to the node after p that is to be deleted
if (to_delete != NULL)
{
if (to_delete->next != NULL) {
to_delete->next->prev = to_delete->prev;
}
if (to_delete->prev != NULL) {
to_delete->prev->next = to_delete->next;
}
// update the tail pointer if to_delete is the tail node...
if (trailer == to_delete) {
trailer = to_delete->prev;
}
delete to_delete;
}
}
removeBefore()
犯了类似的错误。它没有考虑p.prev
在输入时可能为NULL的可能性(当p
是列表中的第一个节点时),或者甚至可能是列表的头节点。它看起来应该是这样的:
void DoublyLinkedList::removeBefore(DListNode *p)
{
DListNode *to_delete = p->prev; //Get to the node before p that is to be deleted
if (to_delete != NULL)
{
if (to_delete->next != NULL) {
to_delete->next->prev = to_delete->prev;
}
if (to_delete->prev != NULL) {
to_delete->prev->next = to_delete->next;
// update the head pointer if to_delete is the head node...
if (header == to_delete) {
header = to_delete->next;
}
delete to_delete;
}
}
话虽如此,通过集中逻辑可以更好地实现逻辑,例如:
void DoublyLinkedList::remove(DListNode *p)
{
if (p = NULL) return;
if (p->next != NULL) {
p->next->prev = p->prev;
}
if (p->prev != NULL) {
p->prev->next = p->next;
}
if (header == p) {
header = p->next;
}
if (trailer == p) {
trailer = p->prev;
}
delete p;
}
void DoublyLinkedList::removeAfter(DListNode *p)
{
remove(p->next);
}
void DoublyLinkedList::removeBefore(DListNode *p)
{
remove(p->prev);
}
话虽这么说,一旦你理解了双链表是如何工作的,你就应该抛弃所有这些代码,而只使用STL std::list
类,这是一个标准的双链表实现。