Как удалить определенный узел в связанном списке?

У меня есть следующий код связанного списка:

#include <iostream>
#include <string>
using namespace std;
#define null 0

class Node
{
public:
    string name;
    int age;
    Node *next;
    Node(string name, int age)
    {
        this->age = age;
        this->name = name;
        this->next = null;
    }
};

class LinkedList
{
private:
    Node *head;
public:
    LinkedList()
    {
        this->head = null;
    }

    void insert(string name, int age)
    {
        Node *nodenew = new Node(name, age);
        nodenew->next = null;
        if (this->head == null)
        {
            this->head = nodenew;
        }
        else
        {
            Node *temp = this->head;
            while (temp->next != null)
            {
                temp = temp->next;
            }
            temp->next = nodenew;
        }
    }

    void print()
    {
        if (this->head == null)
        {
            cout << "Empty";
        }

        Node *temp = this->head;

        while (temp != null)
        {
            cout << temp->name << ", " << temp->age <<endl;
            temp = temp->next;
        }
    }

    void deletePerson(string name){
        Node *temp = this->head;
        Node* prev = null;

        if (temp!=null && temp->name == name)
        {
            this->head = temp->next;
            delete temp;
            return;
        }else
        {
            while (temp != null && temp->name == name)
            {
                prev = temp;
                temp = temp->next;
            }
            if (temp == null)
            {
                return;
            }
            prev->next = temp->next;
            delete temp;     
        } 
    }


};

int main(int argc, char const *argv[])
{
    LinkedList list;
    list.insert("David", 45);
    list.insert("John", 23);
    list.insert("Katty", 78);
    list.insert("Stephanie", 25);
    list.deletePerson("Katty");
    list.print();
    return 0;
}

Я пытаюсь удалить узел по заданному имени следующим методом:

void deletePerson(string name){
        Node *temp = this->head;
        Node* prev = null;

        if (temp!=null && temp->name == name)
        {
            this->head = temp->next;
            delete temp;
            return;
        }else
        {
            while (temp != null && temp->name == name)
            {
                prev = temp;
                temp = temp->next;
            }
            if (temp == null)
            {
                return;
            }
            prev->next = temp->next;
            delete temp;     
        } 
    }

Но когда я компилирую свой код, он ничего не показывает мне в консоли, он просто показывает следующую ошибку кода:

code=3221225477

Я пытался отладить свой код, но vscode просто переключил меня на другой класс, в части prev->next = temp->next; он просто показывает небольшое сообщение, в котором говорится:

Exception has occurred. X
Segmentation fault

Мой ожидаемый результат будет:

David, 45
John, 23
Stephanie, 25

Я надеюсь, что вы можете помочь мне решить эту проблему, спасибо.

Эта страница расшифрует сообщение: https://james.darpinian.com/decoder/?q=3221225477

drescherjm 01.10.2022 00:30

Какой учебник C++ вы используете для изучения C++, который учит вас писать на Java вместо C++? В вашем учебнике C++ объясняется, как использовать синтаксис инициализации элементов в конструкторах вместо неудобного синтаксиса this->, а также использовать тот же неуклюжий синтаксис даже там, где он вообще не нужен?

Sam Varshavchik 01.10.2022 00:32
while (temp != null && temp->name == name) не будет продвигаться вперед, если заголовок не является элементом, который вы ищете, поэтому в этом случае у вас есть prev->next = temp->next;, когда prev является нулевым указателем. Вы уверены, что хотите зациклиться, пока temp->name == name ?
drescherjm 01.10.2022 00:33

Ваш insert метод должен называться append. Кстати, вы можете избежать всего этого специального кода для обработки элемента head, используя указатель на указатель на узел вместо указателя на узел.

jarmod 01.10.2022 00:39

В этом классе Node многое не нравится. Например, как это Человек и Узел одновременно.

sweenish 01.10.2022 01:41

К вашему сведению, если вы используете стиль кодирования, в котором имена членов отличаются от имен параметров, вам не нужно использовать синтаксис this->. Одним из примеров является добавление к именам членов префикса «m_».

Thomas Matthews 01.10.2022 02:10
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
6
328
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ваша проблема настолько проста, что она в этой строке:

while (temp != null && temp->name == name)

должен быть:

while (temp != null && temp->name != name)

как условие зацикливания, вы зацикливаетесь до тех пор, пока либо не дойдете до конца (temp != null), либо имя не будет найдено в этой итерации (temp->name != name).

также в этой строке есть небольшое предупреждение:

prev->next = temp->next;

представьте, если вы не нашли узел, то temp будет нулевым, а строка temp->next; выдаст ошибку, поскольку вы пытаетесь разыменовать нулевой указатель.

Я знаю, что вы справились с этой ситуацией в своем коде, как вы написали:

if (temp == null)
{
     return;
}

но из соображений безопасности или на случай, если ваш компилятор пожаловался на это как на мой, вы должны проверить, являются ли оба prev и temp нулевыми указателями или нет, так и должно быть:

if (null !=  prev && null != temp)
     prev->next = temp->next;

после этого редактирования это вывод:

David, 45
John, 23
Stephanie, 25

Спасибо, сработало, но мне нужно заменить prev->next = temp->next; на if (null != prev && null != temp) prev->next = temp->next;?

riram 01.10.2022 00:58

@riram, нет, вам не нужно, но вы должны, если ваш компилятор жалуется на эту строку, так как мой компилятор жаловался на эту строку, поскольку есть возможность разыменования нулевого указателя

abdo Salm 01.10.2022 01:04

Другие вопросы по теме