使用循环遍历链表

17

我正在阅读关于链表的一些基本操作,发现有两种循环被广泛使用。


struct node {
   int data;
   struct node *next;
}*start=NULL,*tmp;

第一个循环的形式如下:

for(tmp=start;tmp->next!=NULL;tmp=tmp->next);

使用上述循环,现在tmp指针指向链表中的最后一个节点。

第二个循环的形式为:

tmp=start;
while(tmp!=NULL)
{
     // do something
}

我认为它们都可以完成相同的工作,但我不确定。它们之间有什么区别吗?


在 while 循环中,你漏掉了 tmp=tmp->next; - Musa
4
@Musa:// do something 就包括了它。 - user7116
问:“for循环”习语是否等同于相应的“while循环”? 答:是的。 问:这个例子是否有缺陷,因为这个特定的“for()循环”恰好有一个错误? 答:也是的 :) - paulsm4
4个回答

20

我假设你的 while 循环是这样写的。

temp=start;
while(temp!=NULL)
{
     // do something
     temp= temp->next;
}
在你的for循环代码中,当你退出for循环时,temp并没有指向NULL。temp指向了链表的末尾。但是在while循环中,当你退出while循环时,temp指向NULL,并且如果你想在后续步骤中使用它,则没有尾部(除非你将temp分配给其他临时变量来改变程序逻辑)。这是唯一的区别。除此之外并没有太大区别。
你可以通过编写一个小程序并打印结果来检查它。我建议你这样做。

如果我更改temp变量,它会更改原始的链表吗? - User

8
循环不是完全一致的。事实上,你的for循环存在问题。在进入for循环之前,请考虑start==NULL会发生什么情况。
for(tmp=start;tmp->next!=NULL;tmp=tmp->next);

你将start分配给tmp,然后解除tmp的引用,这是一个空指针。我认为你想要下面的代码。
for(tmp=start;tmp!=NULL;tmp=tmp->next);

那个改变使得 forwhile 循环变得相同。

0

问:实际上,“没有”。它们之间没有实质性的区别;它们都可以完成相同的工作。

你总是可以使用等效的“while()”代码编写“for()”循环。


我想知道在循环结束时,“tmp”指针在两种情况下是否都指向最后一个节点? - OneMoreError
@CSSS,根据您当前的定义,while循环唯一的终止方式是tmp == NULL。相比之下,for循环唯一的终止方式是tmp->next == NULL。因此,似乎只有for循环有机会使tmp指向最后一个节点。话虽如此,每个for循环都有一个等效的while循环(反之亦然),因此您可以使它们的行为相同。 - Chris Rice
tmp->next!=NULL 为假时,for循环退出,因此当 tmp->next 为NULL时,它退出,这是当tmp指向最后一个节点时。当 tmp!=NULL 为假时,while循环退出,因此它在tmp为NULL时退出,因此tmp不指向最后一个节点(它没有指向任何东西)。请注意,在tmp指向最后一个节点时,for循环的主体永远不会被执行,因为那是循环退出的时候。 - Eric Postpischil
1
请明确,这个答案是不正确的。循环之间有一个重大区别-请参阅Blastfurnace的答案以获取详细信息。 - Michael Dorst

0

当我需要更改链表时,我使用while循环。例如:

while (root->next)
{
    if(0 == strcmp(root->data,root->next->data))
    {
        temp = root;
        root = root->next;
        free(temp)
    }
    else
    {
        root = root->next;
    }
}

当我需要对链表进行只读访问时,我使用for循环。


你能给出一些选择这样做的理由吗?(可能不行,因为你不是活跃用户,而我已经晚了6年)。 - Michael Dorst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接