I am trying to create an appendToTail function which will add a node to the end of a singly linked list.
I am having trouble in adding a node if the head is NULL(the linked list is empty)
class Node {
private:
Node* next;
int data;
public:
Node(int d, Node* n = NULL)
: data(d)
, next(n)
{
}
void appendToTail(int);
//other trivial functions(getters and setters etc. ) defined and
//declared
};
void Node::appendToTail(int d)
{
Node* end = new Node(d);
Node* n = this;
if (n == NULL)
n = end;
else {
while (n->next != NULL)
n = n->next;
n->next = end;
n->next->next = NULL;
}
end = NULL;
delete end;
}
int main()
{
Node* n = NULL;
n->appendToTail(5);
std::cout << n->getData(); //getData() is a function which
//retrieves the Data member variable
}
I am expecting to get 5 but I am getting an error which appears to be caused because my node remains null.
答案 0 :(得分:0)
现在,对于现代C ++习惯用法,我们使用智能指针而不是原始指针,它为您提供了RAII(资源获取是初始化)机制的好处。另外,如果您想用一种优雅的方法解决问题,则应该引入一个List类,用它可以更清楚地表达一个空列表的概念。它会给出这样的内容:
#include <memory>
#include <iostream>
class List
{
public:
class Node
{
private:
std::shared_ptr<Node> next;
int data;
public:
Node(int d):next(nullptr),data(d){}
inline int getData() const {return data;}
inline std::shared_ptr<Node> getNext() const {return next;}
friend List;
};
List():head(nullptr),tail(nullptr){}
void appendToTail(int );
inline std::shared_ptr<Node> getHead() const {return head;}
inline std::shared_ptr<Node> getTail() const {return tail;}
private:
std::shared_ptr<Node> head;
std::shared_ptr<Node> tail;
};
void List::appendToTail(int d)
{
auto newTail = std::make_shared<Node>(d);
if (head == nullptr)
{
head = tail = newTail;
}
else
{
tail->next = newTail;
tail = newTail;
}
}
int main()
{
List l;
l.appendToTail(5);
std::cout<<l.getHead()->getData();
}
但是您绝对应该选择std::list<T>
或std::vector<T>
。
答案 1 :(得分:0)
很遗憾,您的方法存在一些错误。解释链表时出现语义错误和逻辑错误。让我们从您最初的误会开始。您不能将新尾巴添加到空列表中。因为它是空的。含义,尚不存在。仅当某些对象存在/实例化时,您才能添加尾巴。您不能将某些内容添加到不存在的内容中。因此,以Node * n = nullptr开头的想法在逻辑上是行不通的。
此外,您正在取消引用nullptr(主要错误)。这也是代码的主要问题。什么都没有。您需要先实例化一个对象,然后才能调用其成员函数。
因此,在您可以填充列表之前,需要首先创建/实例化它。因此,您需要使用
在主函数中显式创建第一个节点 Node* n = new Node (5)
然后该列表已存在,从现在开始,您可以通过调用appendToTail添加新成员。
您的代码中还有更多的语义错误,幸运的是没有副作用。
不得在函数中删除“ end”变量。您想保留新分配的内存用于新尾部。但是您通过将'end'设置为nullptr然后调用delete引入了另一个语义错误。删除nullptr是noOp,不会执行任何操作。因此,即使您遇到语义错误,也不会造成任何麻烦。
还有更多:
对于指向Null的指针,您应始终使用nullptr。
然后,您的
if (n == NULL)
始终为假。在此之前,您已将此分配给n。这绝不是NULL。您可以删除if。保留其他语句,
除外n->next->next = NULL;
那不是必需的。构造函数已经为您做到了。如前所述,接下来的2条语句也应删除。
此外,您可能需要阅读更多有关链表的概念。
我希望能有所帮助