[英]C++ linked list append method
I am writing a linked list template class in C++ as an exercise for myself to help me get back into C++ programming. 我正在用C ++编写一个链接列表模板类,作为自己的练习,以帮助我重新开始C ++编程。 I've got the following class definition:
我有以下类定义:
template <typename T>
class List
{
public:
List();
~List();
void append(T data);
void display();
int count();
private:
struct Node
{
T data;
Node *next;
} *head;
};
I have two versions of the append method - one that works and one that doesn't. 我有append方法的两种版本-一种有效,一种无效。 I can't figure out what the difference, in terms of the operations performed, is, and why the second one doesn't work.
在执行的操作方面,我不知道有什么区别,以及为什么第二个不起作用。 Here's the one that works:
这是可行的一种:
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;
}
}
And here's the one that doesn't seem to actually add any elements to the list: 这似乎并没有真正向列表中添加任何元素:
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;
}
}
Any ideas as to why the second version doesn't add any elements? 关于第二个版本为什么不添加任何元素的任何想法? I've been trying it with type T as int.
我一直在尝试将T类型设置为int。
PS Neither version gives any errors or warnings during compilation, nor during runtime. PS在编译期间或运行期间,两个版本均未提供任何错误或警告。
The second method only handles the case where the list is non-empty. 第二种方法仅处理列表为非空的情况。
When the list is empty, the line q->next = p;
当列表为空时,行
q->next = p;
is never reached, so the new element is leaked with no pointer existing to it after p
goes out of scope. 永远不会到达,因此在
p
超出范围后,新元素将被泄漏而指针不存在。
What you want, if you would like to eliminate the special case for empty list, is a Node **
, like thus: 如果要消除空列表的特殊情况,则想要的是
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 };
}
In the first version you change the head
, in the second - you don't. 在第一个版本中,您更改了
head
,在第二个版本中,您没有更改。
Simpler would be: 更简单的是:
template <typename T>
void List<T>::append(T data)
{
p = new Node;
p->data = data;
p->next = head;
head = p;
}
That would also be more logical because entering an item to a linked list shouldn't take O(n) as it does for you... 这也将更合乎逻辑,因为将项目输入到链表中不应该像为您那样使用O(n)...
If you absolutely have to add to the end, do this: 如果您绝对必须添加到末尾,请执行以下操作:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.