我们先关注单个节点:
--------
| data |
--------
| next |
--------
显然,data
member 保存了当前节点的数据。因此,节点只是一对data
持有者,以及指向列表中下一个元素的指针 ( next
)。现在,“链表”这个名称告诉你,这种数据结构是由一些链接连接起来的。所以你可能有多个节点,链接在一起,像这样:
-------- -------- --------
| 5 | | 3 | | 6 |
-------- -------- --------
| next | --->| next | --->| nullptr |
-------- -------- --------
很容易找到列表中的最后一个节点是哪个节点——next
指针的值为 的nullpointer
那个节点,表示列表中没有更多节点。
但是,我们如何找到列表的第一个元素呢?我们将通过保持head
指针 - 指向内存中某处列表的第一个元素的指针来做到这一点:
-------- -------- --------
| 5 | | 3 | | 6 |
-------- -------- --------
| next | --->| next | --->| nullptr |
-------- -------- --------
^
|
head
通过存储head
指针,我们可以像这样轻松地遍历列表:
node *tmp = head; // tmp is our "iterator" through the list
while(tmp != nullptr)
{
// Print the data
cout << tmp->data;
// Move iterator to the next element
// Note that when we print the last element,
// tmp will become nullptr, and the loop will break!
tmp = tmp->next;
}
我应该更清楚我的问题。我知道我可以手动定义每个节点并初始化它们并继续这样做以创建一个列表。但是我如何从节点实现一个列表而不指定我每次想要什么?我想我得到的是我不确定如何从刚刚给定节点定义的节点构建列表。
有一个聪明的技巧可以做到这一点 - 您可以将last
指针保存在某个地方,并且您可以创建一个辅助函数,例如:
void insert(int data)
{
node* n = new node(data);
// If the list is empty:
if(head == nullptr)
{
// This element becomes the first!
head = n;
}
else
{
// Append this element to the end of the
// list
last->next = n;
}
// Update last, as this is the last
// element in the list
last = n;
}