简体   繁体   English

在C ++中遍历单个链接列表

[英]traversing a singly linked list in C++

I was wondering if it is possible to traverse a linked list like this: 我想知道是否可以遍历这样的链表:


currentNode = randomNode;//where randomNode may or may not = firstNode
prevNode = firstNode;
while(prevNode != currentNode && prevNode->link != currentNode)
{
    prevNode = prevNode->link;
}

Is it possible to do this in C++ when I am trying to find the node before currentNode in a singly linked list? 当我尝试在单链列表中的currentNode之前找到节点时,是否可以在C ++中执行此操作?

I trying to implement something like this in a console app for a school assignment so assume that I can't use anything fancy like the boost libraries/list/anything that makes life easier, etc. So basically, I have only fairly primitive datatypes and libraries at my disposal. 我试图在学校应用程序的控制台应用程序中实现类似这样的功能,所以假设我不能使用任何类似的东西,例如boost库/列表/任何使生活更轻松的东西,等等。因此,基本上,我只有相当原始的数据类型,我可以使用的图书馆。

您可能要确保prevNode-> link也不为空引用,以防currentNode实际未链接。

That should work just fine. 那应该很好。 Have you tried it yet? 你尝试过了吗?

The code looks fine, but I would suggest a minor change to your while condition 代码看起来不错,但我建议对您的while条件进行些微更改

while(prevNode != currentNode && prevNode != NULL)

For two reasons 有两个原因

  • Your code, as currently stated, could stop if the node we are looking for is pointed to by either prevNode or prevNode->link (and therefore we will have no idea which particular one of the two points to currentNode -- if we wanted to know, we would have to check with an if condition). 如当前所述,如果您要查找的节点由prevNodeprevNode->link指向,则您的代码可能会停止(因此,我们不知道指向currentNode的两个点中的哪一个特别重要-如果我们想知道,我们将必须检查if条件)。 With the change above, the target node is guaranteed to be stored in prevNode (if at all -- see next point). 通过上述更改,可以确保将目标节点存储在prevNode (如果有的话,请参阅下一点)。
  • For safety's sake, it would be good to check that prevNode is not NULL . 为了安全起见,最好检查prevNode不为NULL However, as Pavel mentions, this test is unnecessary if currentNode is guaranteed to be in the list. 但是,正如Pavel提到的,如果可以保证currentNode在列表中,则不需要进行此测试。

Edit in response to comment 编辑以回应评论

Given that you don't need to know whether currentNode is in prevNode or prevNode->link , and since you want to stop (if possible) on currentNode == prevNode->link , then your original while is fine. 鉴于您不需要知道currentNode是在prevNode还是prevNode->link ,并且由于您想(如果可能)在currentNode == prevNode->link上停止,那么您的原始while很好。 However... 然而...

there is an if statement higher up in the code that prevents prevNode from being null already 在代码中较高的位置有一个if语句,它防止prevNode已经为null

It seems like you're missing the point of why you should check for NULL . 似乎您错过了为什么要检查NULL的要点。 Yes, that's good you check it before, but the reason why we have the NULL check in the loop is in the case where currentNode is not in the list, so you eventually reach the last node. 是的,您之前进行过检查很好,但是在循环中进行NULL检查的原因是currentNode 不在列表中,因此您最终到达了最后一个节点。 Presumably (if you do this like most other linked lists) the value of link for your last node is NULL . 大概(如果您像大多数其他链接列表一样执行此操作),最后一个节点的link值为NULL If so, your current code will eventually end up calling NULL->link which of course will crash your program. 如果是这样,您当前的代码最终将最终调用NULL->link ,这当然会使您的程序崩溃。 That's why you should still check for NULL 这就是为什么您仍然应该检查NULL

while(prevNode != NULL && prevNode != currentNode && prevNode->link!=currentNode)

If you're absolutely sure that currentNode will be in the list, then I guess that check is also unnecessary, but it really is a good habit to get into. 如果您完全确定 currentNode会在列表中,那么我检查也是不必要的,但这确实是个好习惯。

That code will traverse some part of your list, but which part depends on which way your list is linked. 该代码将遍历列表的某些部分,但是哪一部分取决于列表的链接方式。 If it goes from head->tail (read: head node links to a node which links towards tail) then you would traverse your list starting from the random location to the tail. 如果它从头到尾(读:头节点链接到一个节点,该节点链接到尾部),则您将从随机位置开始遍历列表到尾部。 If the links are head<-tail then you would traverse from the random location to the head. 如果链接是head <-tail,那么您将从随机位置遍历到head。 In either case, you would not touch all the nodes in the list. 无论哪种情况,您都不会触摸列表中的所有节点。

All of the above assumes some link list as such: 上面所有这些都假定这样的一些链接列表:

[head]<->[0...N Nodes]<->[Tail]

The links could be either way. 链接可以是任何一种方式。

Also, you could link the head and tail nodes and create a circularly linked list. 另外,您可以链接头节点和尾节点并创建循环链接列表。 In that scenario, it is possible to visit all nodes by simply traversing until you are back to your original node. 在这种情况下,可以通过简单地遍历直到返回原始节点来访问所有节点。

Make sure you consider all of the possible edge cases: 确保考虑所有可能的边缘情况:

  • What happens randomNode equals firstNode ? randomNode等于firstNode会发生什么? What do you return? 你还回来什么? What should you return? 应该还什么?
  • What happens when randomNode is the last node in the list? randomNode是列表中的最后一个节点时会发生什么?
  • What happens when randomNode is NULL ? randomNodeNULL时会发生什么?
  • What happens when randomNode is not in the list? randomNode不在列表中时会发生什么?

Now, not all of these cases may be applicable, depending on if you know anything about randomNode , and some of these may be trivial. 现在,并不是所有这些情况都适用,这取决于您是否对randomNode有所了解,其中有些可能是微不足道的。 But they are all worth thinking about. 但是他们都值得考虑。

If you consider all of these very carefully, there is a simple and elegant solution that handles them all. 如果您非常仔细地考虑所有这些,那么有一个简单而优雅的解决方案可以处理所有这些问题。

You can even have: 您甚至可以拥有:

while (prevNode && prevNode != currentNode)
    prevNode = prevNode->link;

But what you have looks fine. 但是您所拥有的看起来不错。

A small thing I'd change with the code as posted (aside from the possibility discussed in other answers of running off the end of the list if currentNode isn't on the list or other error handling) is that when the while loop is done you don't know if prevNode or prevNode->link points to currentNode . 我要对所发布的代码进行更改(除了在其他答案中讨论的可能性之外,如果currentNode不在列表中或其他错误处理,则在列表末尾运行)的一小件事是,当while循环完成时您不知道prevNodeprevNode->link指向currentNode This isn't a huge problem (since you can easily test for it), but it seems to me that it's best to test for this special case situation before the search, so it's clear that it's a special case. 这不是一个大问题(因为您可以轻松地对其进行测试),但是在我看来,最好在搜索之前针对这种特殊情况进行测试,因此很明显这是一种特殊情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM