这是我编写的删除函数,用于在需要时从链接列表中删除一些节点。
链表按字母顺序存储使用下面的函数,当我尝试删除链表(名为head)的第一个元素时,当我尝试打印链表(使用打印功能)并且程序崩溃时,我收到运行时错误。 我知道这可能是因为没有创建新的头节点。 但我不知道如何解决这个问题。 这可能很简单,但无法弄清楚。 你能帮忙:)
这是删除功能:
void deleteName(someStruct * &head, string name) { someStruct * ptr = head; someStruct * previous; if(head == NULL) { cout << "empty"; } else if(head->name == name) { ptr = head; head = head->next; delete head; } else { while (ptr -> name != name) { previous = ptr; ptr = ptr->next; } previous->next = ptr->next; delete ptr; } }这是打印功能:
void Print(someStruct * head) { someStruct * pointer = head; //List is empty if(head == NULL) { cout << "List is empty" << endl; } else { while(pointer != NULL) { cout << pointer->name; cout << pointer->points << endl; pointer = pointer->next; } } }Here is a delete function I have written to delete some nodes from my linked list when needed.
the linked list is stored as alphabetically orderedUsing below function, when I try to delete the very first element of a linked list (named head), I get an runtime error when I am trying to print the linked list (using the print function) and the program crashes. I am aware that this is probably caused by not creating a new head node. But I do not know how to solve this. This is probably very simple but couldn't figure out. Can you please help :)
this is the delete function:
void deleteName(someStruct * &head, string name) { someStruct * ptr = head; someStruct * previous; if(head == NULL) { cout << "empty"; } else if(head->name == name) { ptr = head; head = head->next; delete head; } else { while (ptr -> name != name) { previous = ptr; ptr = ptr->next; } previous->next = ptr->next; delete ptr; } }this is the print function:
void Print(someStruct * head) { someStruct * pointer = head; //List is empty if(head == NULL) { cout << "List is empty" << endl; } else { while(pointer != NULL) { cout << pointer->name; cout << pointer->points << endl; pointer = pointer->next; } } }最满意答案
else if(head->name == name) { ptr = head; head = head->next; delete head; }这个:
将head的旧值保存到ptr ,这是正确的 推进inout param head ,这也是正确的完全忽略包含要删除的旧节点的ptr ,而是删除当前列表头,使inout参数head指向已删除的节点。
这个位不正确。
只需更改delete head即可delete ptr 。
注意以供参考:构造它的好方法是使用不需要删除的本地sentinel节点。 这将删除head的特殊情况(通过添加永远不会删除临时头的不变量)并简化代码。
void deleteName(someStruct * &head, string name) { if(!head) { cout << "empty"; return; } someStruct tmphead; tmphead.next = head; for (someStruct *prev = &tmphead; prev->next; prev = prev->next) { if (prev->next->name == name) { auto todelete = prev->next; prev->next = todelete->next; delete todelete; // if there can be only one match, just bail out break; // otherwise, if there can be many, go round again // but remember to check whether prev->next is null // if (!prev->next) break; } } head = tmphead.next; }如果你的someStruct太大或太复杂而无法使用像这样的临时头,你可以用一个临时的本地头指针做同样的事情,并使prev指向指针。
else if(head->name == name) { ptr = head; head = head->next; delete head; }This:
saves the old value of head to ptr, which is correct advances the inout param head, which is also correctcompletely ignores ptr, which contains the old node you want to delete, and instead deletes the current list head, leaving the inout param head pointing to a deleted node.
This bit isn't correct.
Just change delete head to delete ptr.
Note for future reference: the good way to structure this is to use a local sentinel node which doesn't need to be deleted. This removes your special case for head (by adding the invariant that your temporary head can never be removed) and simplifies the code.
void deleteName(someStruct * &head, string name) { if(!head) { cout << "empty"; return; } someStruct tmphead; tmphead.next = head; for (someStruct *prev = &tmphead; prev->next; prev = prev->next) { if (prev->next->name == name) { auto todelete = prev->next; prev->next = todelete->next; delete todelete; // if there can be only one match, just bail out break; // otherwise, if there can be many, go round again // but remember to check whether prev->next is null // if (!prev->next) break; } } head = tmphead.next; }If your someStruct is too large or complex to use a temporary head like this, you can do the same with a temporary local head pointer, and make prev a pointer-to-pointer.
更多推荐
发布评论