为链表类型数据结构实现"deleting algorithm"

Implementing "deleting algorithm" for linked list type data structures

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

使用下面的函数,当我尝试删除链表的第一个元素(名为 head)时,当我尝试打印链表(使用 print 函数)和程序时出现运行时错误崩溃。我知道这可能是由于没有创建新的头节点造成的。但我不知道如何解决这个问题。这可能很简单,但无法弄清楚。你能帮忙吗:)

这是删除函数:

 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;
        }
    }
}
else if(head->name == name)
{
    ptr = head;
    head = head->next;
    delete head;
}

这个:

  1. head的旧值保存为ptr,是正确的
  2. 推进 inout 参数 head,这也是正确的
  3. 完全忽略ptr,其中包含要删除的旧节点,而是删除当前列表头,使inout参数head指向已删除的节点.

    这个位不正确。

只需将 delete head 更改为 delete ptr


注意以供将来参考:好的构造方法是使用不需要删除的本地哨兵节点。这删除了 ​​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 块中的 delete head 是问题所在。

将块更改为此:

else if(head->name == name) {
    //ptr = head; You don't have to. You already have initialized ptr with head
    head = head->next;
    delete ptr; //Delete prt not head, head is now the next node which you assigned in previous line
}
else if(head->name == name){
   ptr = head;
   head = head -> next;
   delete ptr;  // change to this statement n you're good to go
}