C++链表遍历

C++ linked-list traversal

本文关键字:遍历 链表 C++      更新时间:2023-10-16

我们的讲师展示了几个处理链表的函数示例(显示所有项目、删除位置、插入为头、插入为尾…)

现在,在那个例子中,我注意到他使用了不同的遍历方法。在某些情况下,他会使用

while(head !=0)
{
    head=head->link;
}

在其他情况下,他使用从一个节点移动到另一个节点。

while(head->link !=0)
{
    head=head->link;
}

这让我很困惑。有理由在某些操作中使用一个而不是另一个吗?

如果head最初是NULL,则第二个变体将导致segfault。

除此之外,第一个变体将迭代N次(其中N是列表中的项目数)。第二个变体将只迭代N-1次。

第一个变量将在遍历后留下指向"null"值的"head"。第二种变体假设head必须指向一个好的(非NULL)head值,并将head指向一个具有NULL link的元素。因此,第二变体对于找到列表的最后元素是有用的,并且第一变体对于计数列表中的项目数量是有用的。

在第一种情况下,他涵盖了列表最初可能为空(head=nil)的情况。在之前,您通常会在循环内部进行任何处理

 head = head->link 

行。

在第二种情况下,他可能知道列表最初并不是空的。在这种情况下,您通常会在之后进行任何处理

 head = head->link 

行,尽管你可以,如果有原因的话,之前也做一些。当然,这也可能不是一个有意识的决定,因为教授也是人;-)

第二个例子实际上有两个问题。始终使用第一个。

正如Oli Charlesworth所说,第一个问题是,如果在头为null的情况下输入循环,将导致空指针解引用(分段错误)。

第二个问题是,循环顶部和head=head->link;语句之间的任何代码都不会出现在链表中的最后一个节点上。因此,如果这个update语句在循环的末尾(这是通常的做法),那么最后一个节点将被完全绕过。所以如果你的代码是这样的:

while(head->link !=0)
{
    dostufftoNode(head);
    head=head->link;
}

然后将为除最后一个节点之外的每个节点调用dostuftoNode()函数。

while(head !=0)
{
    head=head->link;
}

这将

  1. 检查头部是否为空
  2. 设置头对头->链接
  3. 转到一

这将迭代总共n次

while(head->link !=0)
{
    head=head->link;
}

这将

  1. 检查head->link是否为空
  2. 设置头对头->链接
  3. 转到一

这将总共迭代n-1次