我正在编写一个简单的递归代码来反转Java中的链表。奇怪的是,它返回相同的节点。
Node reverse(Node ptr) {
if (ptr.link == null)
return ptr;
Node second = ptr.link;
ptr.link = null;
Node rest = reverse(second);
rest.link = ptr;
return rest;
}
为什么这不起作用?
答案 0 :(得分:2)
您当前的方法不起作用,递归调用返回的rest
值不指向列表中的 last 元素(应该是插入点)对于节点而言,它指向结果的第一个元素。换句话说,这一行没有正确构建输出:
rest.link = ptr;
为了成功反转列表,一种策略是使用累加器参数,因此我们可以在递归展开时插入列表的头部 - 请记住,递归开始以相反的顺序“返回”到列表中的元素。试试这个,这是一个tail-recursive解决方案:
Node reverse(Node ptr, Node acc) {
if (ptr == null)
return acc;
Node second = ptr.link;
ptr.link = acc;
return reverse(second, ptr);
}
像这样调用上面的方法:
Node reversedList = reverse(list, null);
请注意,输入list
将进行就地修改,并且在方法返回后不会相同,任何包含list
引用的变量会受到影响。如果这是一个问题,您应该在将list
传递给reverse()
之前创建{{1}}的副本。
答案 1 :(得分:0)
Oscar是正确的,递归调用的返回值不指向最后一个元素。
还有另一种算法不使用累加器参数:
function reverse(node) {
if (node.next == null)
return node;
var tail = reverse(node.next);
node.next.next = node;
node.next = null;
return tail;
}
答案 2 :(得分:0)
Node reverseNode(Node node){
Node head = null;
While(node.next != null){
Node n = new Node(node.data);
n.next = head;
head = n;
node = node.next;
}
return head;}
您知道您不必编写递归函数