问题是要反转单链表,但我对以下代码感到困惑:
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode temp = head.next;
head.next = null;
ListNode result = reverseList(temp);
temp.next = head;
return result;
}
第6行做什么?
temp.next = head;
没有它,结果将只返回最后一个元素而不是反转列表。
我读它的方式是代码到达第5行,得到结果,经过第6行,然后在第7行返回结果,并继续重复直到完成。第6行如何影响代码?
我很难看到这种递归。有人可以帮忙吗?
答案 0 :(得分:0)
第6行仅在节点之间建立链接。递归一直到最后一个节点并使链接反转。
答案 1 :(得分:0)
递归函数通过使用完全相同问题的较小版本来解决问题。递归函数有两个主要部分:基本案例和递归案例。基本案例是问题的最小版本,我们提供解决方案而不必使用递归。它是递归停止的地方。递归情况假设问题的较小版本提供了正确的解决方案,我们使用这些解决方案来解决更大的版本。
reverseList()将链表的头节点作为输入,反转列表中的每个节点,并返回新反转列表的头节点。
我们假设你有一个链表:
a->b->c->d->e
head指向节点a,temp指向节点b。
在第4行,节点a与原始列表断开连接,产生两个子列表,一个仅包含a,另一个包含以b开头的其他元素。现在,假设第5行正确地反转了以b开头的子列表,我们有:
a
e->d->c->b
头仍然指向a,temp仍指向b,结果指向e(反转子列表的头部)。
为了正确地反转我们的原始列表,我们只需将节点a(head)添加到反向子列表(temp)的末尾。
现在列表是:
e->d->c->b->a
新头指向e。
答案 2 :(得分:0)
编辑:发布完整代码。
我写了一个你可能更了解的替代方案。我还将函数设置为static(getters和setter不用于更简单的解释)。
public class ListNode {
// should be private variables
int value;
ListNode next;
ListNode(int val, ListNode nodeList){
this.value = val;
this.next = nodeList;
}
public static ListNode reverseList(ListNode head) {
if( head.next.next != null)
reverseList (head.next);
head.next.next = head;
head.next = null;
return head;
}
@Override
public String toString(){
String ret = "";
if ( next != null ){
ret = next.toString();
}
ret += String.valueOf(value);
return ret;
}
}
public class Main {
public static void main(String[] args) {
ListNode n0 = new ListNode(4, null),
n1 = new ListNode(3, n0),
n2 = new ListNode(2, n1),
n3 = new ListNode(1, n2),
n4 = new ListNode(0, n3);
System.out.println(n4);
ListNode.reverseList(n4);
System.out.println(n0); // <-- n4 now is the last item, check n0 instead !
}
}
<强>输出强>
43210
01234
您可能更容易在此理解它。在之前绘制,在之后绘制总是有帮助。与this类似,但仅更改框中位置的箭头。