Linked Lists Append To Tail

时间:2019-05-31 11:36:07

标签: c++

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.

2 个答案:

答案 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条语句也应删除。

此外,您可能需要阅读更多有关链表的概念。

我希望能有所帮助