c++ - 链表(删除节点)

标签 c++ linked-list delete-operator

我的问题是,如果用户输入了姓氏,并且链表中有多个相同的姓氏,其中一个姓氏在头节点中。我如何在不删除头节点的情况下删除其他姓氏之一。我尝试了一些我能想到的方法,但删除了所需的节点(这很好),包括头节点(这不是我想要的......)

void NumberList::deleteCertainRecord()
{
string lname = "";

ListNode *ptr;
ptr = head;
string answer;
cout << "Please enter last name: "<<endl;
cin>>answer;
int num = 0;
char confirm;
while (ptr!= NULL){
    lname = ptr -> data.person.getLastName();

    if(lname == answer){
        num++;
        cout << "Person found : ";
        cout << ptr->data.person.getTitle()<<" " << ptr -> data.person.getFirstName() << " " << ptr -> data.person.getLastName() << endl << endl;
        cout << "Do you want to delete his/her record? [Y/N]" << endl;
        do{
            cin >> confirm;
            if(confirm=='Y'||confirm=='y'){
                    ListNode *previousNode;

                    if(isEmpty()){
                        return;
                    }

                    else if(head->data.person.getLastName() == answer){
                        ptr = head->next;
                        delete head; 
                        head = ptr;
                    }

                    else{
                        ptr = head;

                        while(ptr!=NULL && ptr->data.person.getLastName() != answer){
                            previousNode = ptr;
                            ptr = ptr->next;
                        }

                        if(ptr==NULL){
                            cout<< "Node not found!" << endl;
                            return;
                        }
                        else{
                            previousNode->next = ptr->next;
                            delete ptr; 
                        }
                    }
                    cout << endl << "Deleting..."<<endl;
                    cout << "Done!!" <<endl;
                    cout << "Exiting delete function... "<<endl;
                    return;
            }
            else if(confirm=='N'||confirm=='n'){
                break;
            }
            else{
                cout << "invalid input, please enter again!!" << endl;
            }
        }while(confirm!='Y'&&confirm!='y'&&confirm!='n'&& confirm!='N');
        cout << endl;
    }

    ptr = ptr -> next;
}
if (num == 0){
    cout << "\nNo person with the last name ("<< answer << ") was found!" << endl;
    cout << "Exiting delete function... "<<endl;
    return;
}
}

最佳答案

您执行此操作所用的大量代码混淆了实际意图。

  • 你有一个人的链表。
  • 给定一个姓氏,您要枚举列表以查找匹配项。
  • 在发现匹配项后,您希望提示用户确认删除
  • 如果确认删除,解救已发现的节点,保持列表不变,然后将其删除。
  • else如果没有确认,跳到下一个节点,寻找更多匹配

如果该节点实际上是头节点,那么您显然在删除部分时遇到了问题。对于刚接触链表的人来说,特殊情况下的头节点逻辑总是很棘手。幸运的是,如果您使用正确的算法,它是可以完全规避的。假设您的列表以 NULL 正确终止,如果列表为空则包括 NULL 头指针,这样的算法如下:

ListNode ** pp = &head;
while (*pp)
{
    if ((*pp)->data.person.getLastName() == answer &&
         confirmDelete((*pp)->data.person)) // <== TODO: write this function
    {
        ListNode *victim = *pp;
        *pp = victim->next;
        delete victim;
    }
    else
    {   // just advance to next person
        pp = &(*pp)->next;
    }
}

这将正确删除用户,即使他们是列表中的第一个节点并且为您正确推进头指针。它也适用于具有和不具有匹配条件的单节点列表,甚至是 head 为 NULL 的空列表。此技术使用列表中的指针 作为枚举列表的机制;不仅仅是它们的值,实际指针

最后,如果您对列表进行排序,这可以大大提高效率,但我将其留给您。

关于c++ - 链表(删除节点),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22329090/

相关文章:

c++ - 组织项目后Qt中.h文件错误没有这样的文件或目录

java - 如何从自定义 LinkedList 类继承?

c++ - 新建/删除[] 和 VirtualAlloc

c++ - 链接列表的总线错误(核心转储)?

c++ - 关于链表的指针问题

c++ - 将 operator new 和 operator delete 与自定义内存池/分配器一起使用

c++ - delete 和 delete[] 是否等同于基本数据类型

c++ - 使用 QProcess 运行自定义可执行文件,立即退出,退出代码为 1

c++ - 全屏时 WS_CLIPCHILDREN 不起作用

c++ - 找到最大可能三角弦的总和