为链表类型数据结构实现“删除算法”(Implementing “deleting algorithm” for linked list type data structures)

编程入门 行业动态 更新时间:2024-10-26 08:24:23
为链表类型数据结构实现“删除算法”(Implementing “deleting algorithm” for linked list type data structures)

这是我编写的删除函数,用于在需要时从链接列表中删除一些节点。

链表按字母顺序存储

使用下面的函数,当我尝试删除链表(名为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 ordered

Using 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 correct

completely 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.

更多推荐

本文发布于:2023-07-26 02:16:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1269607.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据结构   算法   链表   类型   Implementing

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!