我想知道是否可以遍历这样的链表:
currentNode = randomNode;//where randomNode may or may not = firstNode
prevNode = firstNode;
while(prevNode != currentNode && prevNode->link != currentNode)
{
prevNode = prevNode->link;
}
当我试图在单链表中的currentNode之前找到节点时,是否可以在C ++中执行此操作?
我试图在控制台应用程序中为学校作业实现类似的东西,所以假设我不能使用像boost库/列表/任何使生活更轻松等等任何想象力。所以基本上,我只有公平原始数据类型和库供我使用。
答案 0 :(得分:3)
您可能希望确保prevNode->链接也不是空引用,以防currentNode实际上没有链接。
答案 1 :(得分:1)
这应该工作得很好。你试过了吗?
答案 2 :(得分:1)
代码看起来不错,但我建议您对while
条件进行微小更改
while(prevNode != currentNode && prevNode != NULL)
有两个原因
prevNode
或prevNode->link
指向,您的代码可能会停止(因此我们无法知道这两个点中的哪个特定点到currentNode
- 如果我们想知道,我们必须检查if
条件。通过上述更改,目标节点可以保证存储在prevNode
中(如果有的话 - 请参阅下一点)。 prevNode
是否NULL
。但是,正如Pavel所提到的,如果currentNode
保证在列表中,则不需要进行此测试。编辑以回复评论
鉴于您不需要知道currentNode
是prevNode
还是prevNode->link
,并且因为您想要currentNode == prevNode->link
停止(如果可能),那么你原来的while
没问题。然而...
有一个更高的if语句 阻止的代码
prevNode
为空 已经
您似乎错过了检查NULL
的原因。是的,你之前检查过的很好,但我们在循环中进行NULL
检查的原因是列表中currentNode
不是的情况,所以你最终到达最后一个节点。据推测(如果您像大多数其他链接列表一样执行此操作),您最后一个节点的link
值为NULL
。如果是这样,您当前的代码最终会调用NULL->link
,这当然会导致程序崩溃。这就是为什么你仍然应该检查NULL
while(prevNode != NULL && prevNode != currentNode && prevNode->link!=currentNode)
如果您绝对确定 currentNode
将出现在列表中,那么我猜测该检查也是不必要的,但它确实很好进入的习惯。
答案 3 :(得分:1)
该代码将遍历列表的某些部分,但哪个部分取决于列表的链接方式。如果它从head-> tail(读取:head节点链接到链接到tail的节点)那么你将遍历从随机位置到尾部的列表。如果链接是头部< -tail,那么您将从随机位置遍历到头部。在任何一种情况下,您都不会触摸列表中的所有节点。
以上所有内容都假设了一些链接列表:
[head]<->[0...N Nodes]<->[Tail]
链接可以是任何一种方式。
此外,您可以链接头部和尾部节点并创建循环链接列表。在这种情况下,可以通过简单遍历直到返回原始节点来访问所有节点。
答案 4 :(得分:1)
确保考虑所有可能的边缘情况:
randomNode
等于firstNode
会发生什么?你有什么回报? 你应该返回什么?randomNode
是列表中的最后一个节点时会发生什么?randomNode
NULL
时会发生什么?randomNode
不在列表中时会发生什么?现在,并非所有这些情况都适用,具体取决于您是否了解randomNode
,其中一些可能是微不足道的。但他们都值得思考。
如果你仔细考虑所有这些,就会有一个简单而优雅的解决方案来处理它们。
答案 5 :(得分:0)
你甚至可以:
while (prevNode && prevNode != currentNode)
prevNode = prevNode->link;
但你看起来很好。
答案 6 :(得分:0)
我发布的代码更改了一件小事(除了在列表末尾运行的其他答案中讨论的可能性,如果currentNode不在列表或其他错误处理上),那就是循环完成后,您不知道prevNode
或prevNode->link
是否指向currentNode
。这不是一个大问题(因为你可以很容易地测试它),但在我看来,最好在搜索之前测试这种特殊情况,所以很明显这是一个特例。