【发布时间】:2021-06-07 04:28:22
【问题描述】:
我目前正在学习链接列表,并且已经使用 Append 和 Prepend 方法实现了一个单链表,其中我使用“new”运算符在堆上分配了 Node 类型的对象。我是否需要使用“删除”在堆上释放对象,如果需要,我该怎么做? 这是我的代码:-
class List
{
private:
class Node
{
public:
int data;
Node* next;
Node()
{
data = 0;
next = NULL;
}
Node(const int& data)
{
this->data = data;
}
};
Node* head;
public:
List()
{
head = NULL;
}
void Append(const int&val);
void Prepend(const int&val);
void DisplayAll();
};
void List::Append(const int&val)
{
Node* n = new Node(val); //dynamically allocated
if (head == NULL)
{
head = n;
return;
}
Node* temp = NULL;
temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = n;
}
void List::Prepend(const int&val)
{
Node* node = new Node(val);//dynamically allocated
if (head == NULL)
{
head = node;
return;
}
node->next = head;
head = node;
}
void List::DisplayAll()
{
Node* temp = head;
while (temp != NULL)
{
std::cout << temp->data << ' ';
temp = temp->next;
}
}
【问题讨论】:
-
Any 如果不再需要动态分配的数据,则需要为
deleted,否则会出现内存泄漏。这也包括您的节点。 -
你可以编写一个析构函数(例如
~Node() { ... })来为你做这件事。 (这将是确保班级自行清理的正确方法)例如~Node() { while (head) { Node *victim = head; head = head->next; delete victim; } } -
另外,如果你添加一个
tail指针(例如Node *head, *tail;)并且总是让tail指向你列表中的最后一个节点,你可以在O(1)时间内append无需迭代。 -
旁注:习惯于实现构造函数的初始化列表(不要与
std::initializer_list混淆):List() : head(nullptr) { }。这比默认初始化+赋值更喜欢直接初始化,另外一些成员类型(常量、引用、不可赋值的)only 可以这样初始化。此外,您应该更喜欢 C++ keywords (nullptr) 而不是旧的(过时的?)C macros (NULL)。 -
虽然适合学习,但请记住
std::forward_list已经在做同样的事情,你应该稍后使用它而不是重新发明的轮子。关于学习:下一步是将您的列表转换为模板,以便能够添加任意数据类型。
标签: c++ pointers linked-list c++17 singly-linked-list