int LinkedList::DoStuff()
{
Node *Current = next_;
while ( Current != NULL )
{
Current = Current->next_;
length_++;
}
// At the last iteration we have reached the end/tail/last node
return length_;
}
除了最后一个节点之外没有其他节点。我怎样才能穿过前端的尾端?
答案 0 :(得分:6)
除非你的链表是双重链接的,否则这很难做到。递归是一种方式,假设你没有那么大的列表,你将耗尽堆栈空间,就像这样(伪代码):
DoStuffBackwards (currNode) {
if (currNode != NULL) {
DoStuffBackwards (currNode->next);
// Process currNode here.
}
}
DoStuffBackwards (firstNode);
这是有效的,因为你继续为下一个节点调用DoStuffBackwards()
,直到你耗尽列表然后,当你回滚递归堆栈时,你处理每个节点。
答案 1 :(得分:1)
如果您只想从最后一个节点向后退到当前节点,那么Pax的答案(使用递归)是您最好的选择,请参阅下面的我的版本。如果您当前的节点不是非循环单链表的头部,并且您想从当前节点转到头节点,则不可能。
int LinkedList::DoStuff()
{
return DoStuffBackward(next_, 0);
}
int LinkedList::DoStuffBackward(Node* node, int n)
{
if (!node)
{
return n;
}
int len = DoStuffBackward(node->next_, n + 1);
std::cout << "doing stuff for node " << n << std::endl;
return len;
}
答案 2 :(得分:1)
这有家庭作业的气味,所以没有代码,但这里是一个不需要递归的解决方案的概述:
如果要向后浏览列表,可以选择重新链接列表,以便在遍历列表时查找结尾。然后,当您重新遍历列表(以与原始列表相反的顺序访问节点)时,您将重复与之前相同的重新链接,并且列表以其原始顺序结束。
这在概念上很简单,但正确处理指针和链接(特别是在列表的开头和结尾)可能有点棘手。
答案 3 :(得分:0)
您的链接列表是双重链接还是单链接?如果每个节点内没有 previous 指针,则不能向后遍历。
我还建议您发布更多代码并花时间让您的问题可读。
答案 4 :(得分:0)
递归可以起作用,就像构建辅助数据结构一样,例如,对于原始列表的每个元素都有一个条目的数组。如果你想要一个单线程列表的解决方案,而不需要O(n)额外的存储空间,那么最好的办法就是按照迈克尔的建议来反转列表。我为此写了一个例子,[但考虑到对家庭作业的担忧,我会把它留下来]。关于反转列表的一个注意事项:如果有任何其他数据结构保存指向原始列表的指针,并且您可能在遍历期间访问它们,那么如果它们需要在反转时访问列表,它们将无法工作,并且这如果他们试图修改列表,可能会导致数据损坏。
更新:好的,这是(C ++)例程来反转列表。但它尚未经过测试。而且我会注意到,如果这是家庭作业,海报仍然需要弄清楚如何正确使用这个例程来得到一个完整的答案。
Node *ReverseList(Node *head) {
// Reverse a single-threaded list in place, return new head
Node *prev=NULL;
Node *cur=head;
while (Node *next=cur->next_) {
cur->next_ = prev;
prev = cur;
cur = next;
}
cur->next_ = prev;
return cur;
}
答案 5 :(得分:0)
将列表推入堆栈,然后将其弹出。