【发布时间】:2019-06-06 07:55:09
【问题描述】:
这是问题所在:https://leetcode.com/problems/reverse-linked-list/
我知道解决方案(而且它在互联网上到处都是复制粘贴的),但我不明白 其中的一部分是如何工作的... 所以:
struct ListNode{
int data;
ListNode* next;
};
ListNode* reverseList(ListNode* head) {
if (!head || !(head -> next)) {
return head;
}
ListNode* node = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return node;
}
这行得通。
现在我通过调试器得到它并看到我不明白的东西......
假设我们有一个链表:
1->2->3->NULL
1 ) 我们已将最后一个 3->Null 部分传递给 ListNode* node = reverseList(head->next);
它确实是return head;,现在是ListNode* node = 3->NULL;
好的,node == 3->NULL 和 head == 2->3->NULL
2) 让我们转到head->next->next = head:
现在head == 2->3->2->3... 但是为什么 node == 3->2->3->2... ???
它们是如何连接的?我在这里完全糊涂了。
3) 在下一行head -> next = NULL 我们可以看到它再次影响head 和node:
如您所见,我不明白node 和head 之间的联系。
所以我不明白它是如何工作的,我觉得我不明白这些链接列表一般是如何工作的。
也许有人可以帮助我?欣赏它。
【问题讨论】:
-
"现在
head == 2->3->2->3..。但是为什么node == 3->2->3->2...???"反转函数使用 chaining 反转列表。注意 recursive 调用ListNode* node = reverseList(head -> next);在函数中的位置。之后returns——会发生什么?每次递归调用之后都会对指针进行哪两次重新分配? -
@DavidC.Rankin,嗨! "ListNode* 节点 = reverseList(head -> next);"据我了解,返回
node == 3->null(您可以在调试器的屏幕截图中看到它)。并将其返回到堆栈具有node == 2->3->null的程序状态; “每次递归调用后,都会对指针进行哪两次重新分配?”你的意思是这些行吗:head -> next -> next = head; head -> next = NULL但它们是在head上制作的,而不是在node上制作的。那么为什么node也会受到影响呢?这是我的问题。 -
递归函数 "Unwind" 返回。按照递归 "Winds-In" 的路径直到
head == NULL | head->next == NULL,然后将返回跟踪为递归 "Unwinds"。 (这就是你必须如何看待递归)。在第一个return控制 "unwinds" (返回到)之前的函数调用,其中两个赋值是在该级别递归 returns 之前进行的......(其中 “unwinds”(返回)之前的调用)。这就像从洋葱的中心开始,然后从中心向外工作,然后一层一层地……用铅笔和纸做一张桌子——这很有帮助:) -
@DavidC.Rankin,感谢您的支持,但我想我以前就知道这一切,这对我的问题没有帮助。也许你理解的更深,但你的解释不是我理解的水平,或者你不理解。我不知道哪个是正确的,更喜欢先思考(你比我聪明,只是无法向我智商的人解释)......
-
请注意,如果列表不太长,它虽然有效,但效率低下。迭代解决方案更可取。
标签: c++ recursion linked-list