C ++链表附加方法

时间:2011-09-25 00:30:23

标签: c++ templates linked-list

我正在用C ++编写一个链表模板类作为练习,帮助我重新进入C ++编程。我有以下类定义:

template <typename T>
class List
{
public:
    List();
    ~List();

    void append(T data);
    void display();
    int  count();

private:
    struct Node
    {
        T data;
        Node *next;
    } *head;
};

我有两个版本的append方法 - 一个有效,另一个没有。我无法弄清楚在执行的操作方面有什么不同,以及为什么第二个不起作用。这是有效的:

template <typename T>
void List<T>::append(T data)
{
    if (head == NULL)
    {
        head = new Node;
        head->data = data;
        head->next = NULL;
    }
    else
    {
        Node *p = head, *q;
        while (p != NULL)
        {
            q = p;
            p = p->next;
        }

        p = new Node;
        p->data = data;
        p->next = NULL;
        q->next = p;
    }
}

这里似乎没有在列表中添加任何元素:

template <typename T>
void List<T>::append(T data)
{
    Node *p = head, *q = head;

    while (p != NULL)
    {
        q = p;
        p = p->next;
    }

    p = new Node;
    p->data = data;
    p->next = NULL;
    if (q != NULL)
    {
        q->next = p;
    }
}

关于为什么第二个版本不添加任何元素的任何想法?我一直在尝试将类型T作为int。

P.S。这两个版本在编译期间或运行时都没有给出任何错误或警告。

2 个答案:

答案 0 :(得分:1)

第二种方法只处理列表非空的情况。

如果列表为空,则永远不会到达行q->next = p;,因此在p超出范围后,新元素将被泄露而没有指针存在。

如果您想消除空列表的特殊情况,您想要的是Node **,如下所示:

template <typename T>
void List<T>::append(T data)
{
    Node** q = &head; /* head acts as the first Node::next link */

    /* invariant: q points to some Node::next field (or head, which acts like one) */
    while (*q)
        q = &(*q)->next;

    /* invariant: q points to the Node::next field at the end of the chain, which is currently NULL */
    *q = new Node { data, nullptr };
}

答案 1 :(得分:0)

在第一个版本中,您更改了head,在第二个版本中,您没有。

更简单的是:

template <typename T>
void List<T>::append(T data)
{
    p = new Node;
    p->data = data;
    p->next = head;
    head = p;
}

这也更合乎逻辑,因为将一个项目输入到一个链表中不应该像你那样采用O(n)......

如果你必须添加到最后,请执行以下操作:

template <typename T>
void List<T>::append(T data)
{
    p = new Node;
    p->data = data;
    p->next = NULL;
    if (tail)
        tail->next = p;
    else // first time
        tail = head = p;
}