1

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

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

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

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

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

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

4

5 回答 5

1

head如果最初是,则第二个变体将导致段错误NULL

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

于 2012-04-03T20:10:44.830 回答
1

第一个变体将在遍历后使“head”指向“null”值。第二个变体假设 head 必须指向一个好的(非 NULL) head 值以开始,并且会让 head 指向一个具有 null 的元素link。因此,第二个变体对于查找列表的最后一个元素很有用,而第一个变体对于计算列表中的项目数很有用。

于 2012-04-03T20:14:12.787 回答
0

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

第一个问题正如 Oli Charlesworth 所说,如果在 head 为 NULL 的情况下进入循环,它将导致空指针取消引用(分段错误)。

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

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

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

于 2012-04-03T20:15:37.573 回答
0
while(head !=0)
{
    head=head->link;
}

这将

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

这将总共迭代 n 次

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

这将

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

这将总共迭代 n-1 次

于 2012-04-03T20:16:59.443 回答
0

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

 head = head->link 

线。

在第二种情况下,大概他知道列表最初不是空的。在这种情况下,您通常会在

 head = head->link 

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

于 2012-04-03T20:15:10.197 回答