这是问题所在: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
之间的联系。
所以我不明白它是如何工作的,我感觉我也不了解那些链表是如何工作的。
也许有人可以帮我吗?赞赏。
答案 0 :(得分:2)
很不幸,我没有足够的声誉来发表评论,所以我将发表一个答案,希望对您有所帮助。我将使用绘画图片使事情更容易可视化。让我们开始吧:
比方说,我们有列表1-> 2-> 3->,所以它是这样开始的:
现在,我们启动函数并运行直到到达第一个递归为止,在该递归中它以新的头开头,并且出现以下情况:
然后该函数再次运行,我们得到以下结果:
然后我们从一个新的head(3)开始,但是这里的最后一个函数返回head是因为满足if
条件head->next == NULL
。因此,我们有:
然后,我们遵循该函数,直到最后更改head->next->next = head
和head->next = NULL
为止,所以我们有:
然后函数返回节点,我们返回到原始调用。然后,我们执行相同的步骤,最后得到:
最后,该函数返回节点,所以我们最终得到:
希望这对您有帮助,但对答案质量很差感到抱歉,但是我发现在可视化时更容易解决递归,而可视化的最简单方法是绘图。
答案 1 :(得分:0)
好的,可能我自己也找到了答案。 再次,问题出在这里:
ListNode* node = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return node;
我的问题是为什么更改了head
的字符串2和3也会影响(更改)node
?
这是因为node
是一个指针,它“指向”与head->next
相同的内存地址。
您实际上可以在第一个屏幕截图中看到它:
0x100300020是node
的地址
0x100300020是head->next
的地址
它们指向内存中的相同地址。
所以,当我们这样做时:
head -> next -> next = head;
head -> next = NULL;
我们也将其更改为node
指向的地址中“已存储的内容”。