C++如何在不丢失内存的情况下删除节点?

标签 c++ linked-list nodes

我无法让这个单链表在不丢失内存的情况下工作。我已经用谷歌搜索了,据我所知,我做了最建议的事情。我也尝试过“free(deleteNode)”而不是“delete deleteNode”。有人认为他们知道答案吗?

提前谢谢你。

我正在尝试使用此代码片段插入和删除

List l{};
l.insert(5);
l.remove(5);

我敢打赌错误出在我的 remove 函数中:

void List::remove(int input){

    if(top -> getValue() == input){
        Node * deleteNode = new Node;
        deleteNode = top;
        top = top -> getNext();
        delete deleteNode;
        amount--;
        return;
    }

    Node * tmpNode;
    tmpNode = new Node(top);

    while(tmpNode -> getValue() != 0){
        if(tmpNode -> getNext() -> getValue() == input){
            Node * deleteNode;
            deleteNode = new Node(tmpNode -> getNext());
            tmpNode -> setNext(deleteNode -> getNext());
            deleteNode -> setNext(nullptr);
            delete deleteNode;
            amount--;
            return;
        }
        tmpNode = tmpNode -> getNext();
    }
}

我的抄送文件:

#include <cstddef>
using namespace std;
#include "List.h"
#include <iostream>

List::List() : amount(0), top(nullptr) {
}

List::List(Node* input) : List(){
    top = input;
}

List::~List(){//destructor
    while( top != nullptr){
        remove( top -> getValue());
    }
}

List::Node::~Node(){//destructor
    next = nullptr;
    //this =NULL;
}

    List::List(List const& other) : List(){
        *this = other;
    }

    List::List(List && other) : List(){ // move constructor
       Node* tmpNode = other.top;
       other.top = top;
       top = tmpNode;
       int tmpAmount = size();
        setSize(other.size());
        other.setSize(tmpAmount);
    }

    List & List::operator=(List && other){ // move assignment
        Node* tmpNode = other.top;
        other.top = top;
        top = tmpNode;
        int tmpAmount = size();
        other.size();
        setSize(other.size());
        other.setSize(tmpAmount);
        return *this;
    }

    List & List::operator=(List const& other){// copy assignment
        Node * tmpNode; 
        tmpNode = other.top;

        while(tmpNode != nullptr){
            insert(tmpNode -> getValue());
            tmpNode = tmpNode -> getNext();
        }

        return *this;
    }

void List::setSize(int input){
    amount = input;
}

void List::insert(int input){
    Node* newNode;
    newNode = new Node(input);
    if(!top){
        top = newNode;
        amount++;
        return;
    }

    if(input > top -> getValue()){
        newNode -> setNext(top);
        top = newNode;
        amount++;
        return;
    }

    top -> putIterator(newNode);
    amount++;
    return;
}

string List::print(){
    if(top == nullptr){
        return "";
    }
    string output = to_string(top -> getValue());
    if(top -> getNext() == nullptr){
        return output;
    }
    return top -> getNext() -> print(output);
}

void List::remove(int input){

    if(top -> getValue() == input){
        Node * deleteNode = new Node;
        deleteNode = top;
        top = top -> getNext();
        delete deleteNode;
        amount--;
        return;
    }

    Node * tmpNode;
    tmpNode = new Node(top);

    while(tmpNode -> getValue() != 0){
        if(tmpNode -> getNext() -> getValue() == input){
            Node * deleteNode;
            deleteNode = new Node(tmpNode -> getNext());
            tmpNode -> setNext(deleteNode -> getNext());
            deleteNode -> setNext(nullptr);
            delete deleteNode;
            amount--;
            return;
        }
        tmpNode = tmpNode -> getNext();
    }
}

List::Node List::find(int input){
    return iterate(input).getNext();
}

List::Node List::iterate(int input){
    return top -> iterate(input);
}

bool List::isEmpty(){
    if(size()==0){
        return true;
    }
    return false;
}

int List::size(){
    return amount;
}

List::Node::Node(int input, Node &nextInput){
    value = input;
    next = &nextInput;
}

List::Node::Node(int input){
    value = input;
    next = nullptr;
}

List::Node::Node(const Node* input){
    *this = *input;
}

List::Node* List::Node::getNext(){
    return next;
}

void List::Node::setNext(Node* input){
    next = input;
}

int List::Node::getValue(){
    return value;
}

/*
void List::Node::deleteNode(){
    delete *this;
}*/

void List::Node::putIterator(Node* newNode){
    if (next == nullptr){
        next = newNode;
        next -> setNext(nullptr);
        return;
    }

    if(getValue() == newNode -> getValue()){
        newNode -> setNext(getNext());
        setNext(newNode);
        return; 
    }

    if(next -> value < newNode -> value && value > newNode -> value){
        newNode -> setNext(getNext());
        setNext(newNode);
        return;
    }

    next -> putIterator(newNode);
    return;
}

string List::Node::print(string input){
    input = input + ", " + to_string(value);
    if(next == nullptr){
        return input;
    }
    return next -> print(input);
}

List::Node List::Node::iterate(int input){
    if (next -> value==input){
        return *this;
    }
    if (next -> value==0){
        return nullptr;
    }

    return next ->iterate(input);
}

bool List::Node::operator!() const{
    if(value == 0){
        return true;
    }
    return false;
}

我的头文件:

#ifndef _LIST_H_
#define _LIST_H_
#include <string>

class List
{
  public:
    List();

    ~List(); //destructor
    List(List const &other);
    List(List &&other);                 // move constructor
    List &operator=(List &&other);      // move assignment
    List &operator=(List const &other); // copy assignment

  class Node
    {
      public:
        Node() = default;
        ~Node();
        Node(int input, Node &nextInput);
        Node(int input);
        Node(const Node *input);
        Node *getNext();
        void setNext(Node *input);
        int getValue();
        Node iterate(int input);
        void putIterator(Node *newNode);
        void deleteNode();
        bool operator!() const;
        std::string print(std::string input);

      private:
        int value;
        Node *next;
    };

    List(Node* input);
    void insert(int input);
    void remove(int input);
    Node iterate(int input);
    int size();
    bool isEmpty();
    Node find(int input);
    std::string print();
    void setSize(int input);

   private:

    Node *top;
    int amount;
};

#endif

最佳答案

为什么要在 remove() 中创建一个新节点?

接下来,将 getter、setter 和所有其他废话添加到 Node(这是 List 的实现细节)只会使 List< 复杂化。全部删除(除了 ctor,也许)。

考虑使用双重间接或其他方式来消除特殊情况和由此产生的容易出错的重复:

void List::remove(int x) {
    auto p = &top;
    while (*p && p[0]->value != x)
        p = &p[0]->next;
    if (*p)
        delete std::exchange(*p, p[0]->next);
}

备选方案:

void List::remove(int x) {
    auto curr = top;
    curr = nullptr;
    auto next = top;
    while (next && next->value != x) {
        curr = next;
        next = next->next;
    }
    if (!next)
        return;
    (curr ? curr->next : top) = next->next;
    delete next;
}

关于C++如何在不丢失内存的情况下删除节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54190331/

相关文章:

node.js - 使用nodejs进行多人游戏的最佳实践

c++ - catch(...) 实际上捕获所有异常吗?

c++ - 外部参照环绕错误 : 'void' function returning a value

java - 使用 map().reduce() 初始化链表节点

c - 在链表中动态存储字符串

javascript - javascript .childNodes 和 .children 之间的区别

algorithm - 找到所有边的最小最高成本的算法是什么?

c++ - 二叉搜索树中具有最小值的节点

c++ - 如何在 C++ 中将数字与数字分开?

c - 如何告诉 gcc 不要优化特定函数