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

0

Я должен написать дважды связанный список, я пытаюсь реализовать метод erase(Type obj) который принимает аргумент obj и проходит через список и удаляет каждый узел, который имеет элемент obj.

Проблема, с которой я столкнулся, заключается в том, что я выполняю итерацию через связанный список спереди, и когда я нахожу узел, у которого есть элемент obj, я изменяю следующие/предыдущие указатели узлов до и после узла с элементом obj. Однако я не удаляю узел с самим obj, насколько я знаю, c++ не имеет сборки мусора, поэтому узел, который имел obj, все еще где-то висит в воздухе. Как удалить это?

Мое удаление()

template <typename Type>
int Double_list<Type>::erase( Type const &obj ) {
if (empty()){
    return 0;
}
if (size() == 1 && head()->retrieve() == obj){
    list_head = nullptr;
    list_tail = nullptr;
    list_size--;
    return 1;
}

//Counter to hold the number of items deleted
int count = 0;
    //Iterating through the linked list
for (Double_node<Type> *ptr = head(); ptr != nullptr; ptr = ptr->next()){
    if (ptr->retrieve() == obj){
        ptr->previous_node->next_node = ptr->next();
        ptr->next()->previous_node = ptr->previous();
        count++;
        // delete ptr; // This stops me from iterating through the for loop
        list_size--;
    }
}
return count;
}
  • 3
    После того, как вы скорректировали свои указатели, используйте ключевое слово delete чтобы фактически удалить объект (освободите его память).
  • 0
    @ooga Incase Я delete ptr после изменения указателей узлов до и после узла obj, после чего я больше не могу перемещаться по связанному списку. Поскольку после удаления я не могу получить доступ к ptr-> next ()
Показать ещё 2 комментария
Теги:
doubly-linked-list
erase

2 ответа

1
Лучший ответ

Пока вы просматриваете свой список, вы делаете это с помощью указателя на узлы, которые имеют тип Double_node<Type> *, что означает, что он был размещен где-то и может быть удален простым delete ptr, но поскольку вы используете его также для получения следующего элемент в списке, вы должны быть осторожны и помнить его преждевременно, поэтому это должно быть что-то вроде:

Double_node<Type> *ptr_next = 0;
for (Double_node<Type> *ptr = head(); ptr != nullptr; ptr = ptr_next) {
     ptr_next = ptr->next ();
     if (ptr->retrieve() == obj){
     if (ptr->previous_node)
       ptr->previous_node->next_node = ptr->next();

     ptr->next()->previous_node = ptr->previous();
     count++;
     list_size--;
     delete ptr;
    }

Я считаю, что это должно сделать трюк.

  • 2
    Это: ptr->previous_node->next_node вызовет неопределенное поведение, если искомый узел оказался головным узлом, и в этом случае ptr->previous_node равен NULL .
  • 0
    @WhozCraig Спасибо, я отредактировал ответ, чтобы это исправить.
Показать ещё 2 комментария
0

При удалении указателей и объектов, называемых delete, существует синтаксис. пример кода:

obj *temp = getCurrentNode();
//set pointers in nodes to the correct places
delete temp; //This releases all of the memory used in the object back to the OS
temp = NULL;//good practice to set this to null, since it points to non-allocated memory
//but exiting the function will make the pointer 'temp' useless, anyway.
  • 0
    как уже упоминалось в моем втором комментарии, Incase, я действительно удаляю ptr после изменения указателей узлов до и после узла obj, после чего я больше не могу перемещаться по связанному списку. Поскольку после удаления я не могу получить доступ к ptr-> next ()
  • 0
    Вы сохраняете адрес памяти во временном указателе, как указано выше, исправляете ссылки, чтобы игнорировать удаляемую часть, и удаляете его с помощью временного указателя. Это решает вашу проблему невозможности доступа к объекту после изменения ссылок, а также позволяет освободить пространство объекта в памяти обратно в ОС.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню